TGViewer
Гепардово гнездо Гепардово гнездо @gepardchan · 617 subscribers
Post #87 833
Перемещение в самого себя в C++

Известно, что при реализации копирования в C++ принято учитывать случай, когда мы хотим скопировать объект в себя:

Foo &operator=(const Foo &other) {
if (this == &other) {
return *this;
}
// ...
return *this;
}

Вопрос: надо ли учитывать аналогичный случай при реализации перемещающего присваивания? Давайте посмотрим, что делает STL на примере вектора:

std::vector<int> v{1, 2, 3, 4};
v = std::move(v);
std::cout << v.size() << std::endl;

Думаете, что этот код выведет 4? А вот и нет! При компиляции в GCC под libstdc++ мы получим вывод 0 (т.е. вектор опустеет)! То есть, авторы STL не считают, что перемещение объекта самого в себя должно быть эквивалентно no-op и при реализации вектора не костылили этот случай.

Почему так? Пойдем на StackOverflow и возьмем оттуда цитату из Стандарта:

Each of the following applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.
- ...
- If a function argument binds to an rvalue reference parameter, the implementation may assume that this parameter is a unique reference to this argument. [Note: If the parameter is a generic parameter of the form T&& and an lvalue of type A is bound, the argument binds to an lvalue reference (14. 8. 2. 1) and thus is not covered by the previous sentence. — end note] [Note: If a program casts an lvalue to an xvalue while passing that lvalue to a library function (e.g. by calling the function with the argument move(x)), the program is effectively asking that function to treat that lvalue as a temporary. The implementation is free to optimize away aliasing checks which might be needed if the argument was an lvalue. — end note]

Здесь приводится более общее утверждение: считается, что если функция из STL принимает rvalue-ссылку на объект, то ссылка считается уникальной. А в случае перемещения в самого себя нам надо еще иметь вторую ссылку на тот же объект: то, куда мы присваиваем.

Стоит отметить, что правила выше относятся только к STL, но не к пользовательскому коду. Но если перемещение в себя не работает даже со стандартными классами, то есть ли вообще какой-то смысл поддерживать этот случай в своем коде?
  • 🔥 8
  • 🤡 2
  • 👍 1
More from @gepardchan
  1. Sep 7, 2025Итак, расскажу о том, что я сделал еще давно, но про что все никак не доходили руки написа…
  2. Dec 10, 2024https://habr.com/ru/post/472970/ Статья 2019 года, то есть довольно старая, с учетом того,…
  3. Nov 30, 2024Сегодня читал про то, как Debian везде перешел на 64-х битный time_t. Изменение войдет в р…
  4. Nov 26, 2024https://www.ryanliptak.com/blog/every-rc-exe-bug-quirk-probably/ Не знаю, как вы, а я прос…
  5. Nov 22, 2024Еще про проклятые фичи баша https://yossarian.net/til/post/some-surprising-code-execution-…
  6. Nov 21, 2024Про переписывание истории В баше (а точнее, в GNU Readline, который используется башом), е…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →