И всю move семантику. И у меня даже готовился доклад про то, как я его ненавижу, с кучей веселых примеров, которые не приехали еще сюда в дурку. Где я собрал в кучку почему именно я его ненавижу, но там получилось очень много и очень неструктурированно, поэтому доклад до сих пор в разработке.
Но вот один пример, который я выкину таки сюда.
int main() {
std::map<int, std::unique_ptr<int>> m;
m.emplace(1, std::make_unique<int>(42));
auto p = std::make_unique<int>(100);
auto [it, inserted] = m.emplace(std::make_pair(1, std::move(p)));
}
Здесь классика классика.
Мапа из чего-то в в unique_ptr. Ну кто так не делал (здесь должна быть ссылке на open-source пример, но у меня жопа горит).
Дальше мы делаем emplace.
Return value
A pair consisting of an iterator to the inserted element (or to the element that prevented the insertion) and a bool value set to true if and only if the insertion took place.
Ну и вот второй emplace с ключом 1 вернет false.
А что же произойдет с p?
Он занулится, потому что мы его мувнули в функцию.
int main() {
std::map<int, std::unique_ptr<int>> m;
m.emplace(1, std::make_unique<int>(42));
auto p = std::make_unique<int>(100);
auto [it, inserted] = m.emplace(std::make_pair(1, std::move(p)));
std::cout << std::boolalpha;
std::cout << "inserted = " << inserted << '\n';
std::cout << "p is null = " << (p == nullptr) << '\n';
std::cout << "*it->second = " << *it->second << '\n';
}
Выводит
inserted = false
p is null = true
*it->second = 42
Тоесть в мапу значение не поместили, а из указателя оно пропало... Восхитительно.
Притом что если делать std::move "на месте" такого не происходит.
int main() {
auto p = std::make_unique<int>(100);
std::move(p);
std::cout << std::boolalpha;
std::cout << "p is null = " << (p.get() == nullptr) << '\n';
}
p is null = false
Да, это чинится тем, что мы убираем
make_pair, но это в тестовом примере, где это легко заметить. И когда уже знаешь проблему.Я задолбался ловить такие приколы с move.