Когда MSVC движет движением std :: set , он также движет Allocator. Позже, когда он разрушает перемещенную из набора, он использует распределитель, чтобы разобраться с элементом. Следующее объясняет, что делает MSVC (см.
Https://godbolt.org/z/4ts7z4tj8 для кода, который фактически генерирует трассировку действий распределения):
Код: Выделить всё
#include
int main() {
// Allocator actions when default-constructing s1:
// 1. Default-construct s1's allocator
// 2. Use s1's allocator to allocate a node
std::set s1;
// Allocator actions when inserting into s1:
// 3. Use s1's allocator to allocate a node
s1.insert(1);
{
// Allocator actions when move-constructing s2 from s1:
// 4. Move-construct s2's allocator from s1
// 5. Use s2's allocator to allocate a node
auto s2 = std::move(s1);
// Allocator actions when s2 goes out of scope:
// 6. Use s2's allocator to deallocate a node
// 7. Use s2's allocator to deallocate a node
// 8. Destruct s2's allocator
}
// Allocator actions when s1 goes out of scope:
// 9. Use the s1's allocator to deallocate a node
// 10. Destruct s1's allocator
}
Обратите внимание, что (4) движется из распределения S1, и (9) использует распределитель S1. std :: function и MSVC сбои при выборе перемещенного от std :: function . (Я могу обойти это, сделав конструктор движения и оператора движения и оператора с помощью движения, а не перемещать его. Но это жаль, потому что тогда операции перемещения могут выделять и бросить, и, возможно, это делает их немного медленнее.) Реализация? Сделайте мой обходной путь недействительным, хотя для меня может быть нормально объявлять конструктор движения как noexcte и позвонить в прекращение об отказе от распределения. propagate_on_container_move_assignment , но мой вопрос не об этом. Поведение идентично независимо от propagate_on*.)>
Подробнее здесь:
https://stackoverflow.com/questions/796 ... ndard-cont