Возможный дубликат:
Как обеспечить семантику перемещения при увеличении вектора?
insert
,push_back
иemplace
(_back
) могут вызвать перераспределениеstd::vector
. Я был озадачен, увидев, что следующий код копируетэлементы вместо перемещенияих при перераспределении контейнера.#include
#include struct foo { int value; explicit foo(int value) : value(value) { std::cout << "foo(" << value << ")\n"; } foo(foo const& other) noexcept : value(other.value) { std::cout << "foo(foo(" << value << "))\n"; } foo(foo&& other) noexcept : value(std::move(other.value)) { other.value = -1; std::cout << "foo(move(foo(" << value << "))\n"; } ~foo() { if (value != -1) std::cout << "~foo(" << value << ")\n"; } }; int main() { std::vector foos; foos.emplace_back(1); foos.emplace_back(2); } На моей конкретной машине с использованием моего конкретного компилятора (GCC 4.7) это напечатает следующее:
foo(1) foo(2) foo(foo(1)) ~foo(1) ~foo(1) ~foo(2)
Однако при удалении конструктора копирования (
foo(foo const&) = delete;
) генерируется следующий (ожидаемый) вывод:foo(1) foo(2) foo(move(foo(1)) ~foo(1) ~foo(2)
Почему так? Разве перемещение в целом не будет более эффективным или, по крайней мере, не намного менее эффективным, чем копирование?
Следует отметить, что GCC 4.5.1 делает то, что ожидалось— это регрессия в GCC 4.7 или какая-то хитрая оптимизация, потому что компилятор видит, что мой объект дешево скопировать (но как ?!)?
Также обратите внимание, что я удостоверился, что это вызваноперераспределением, экспериментально поместив
foos.reserve(2);
перед вставками; это не приводит к выполнению ни копирования, ни перемещения.