Por que realocar uma cópia de vetor em vez de mover os elementos? [duplicado]
Duplicata Possível:
Como impor a semântica de movimento quando um vetor cresce?
insert
, push_back
eemplace
(_back
) pode causar uma realocação de umstd::vector
. Fiquei perplexo ao ver que o seguinte códigocópias os elementos em vez demovendo-se enquanto realoca o recipiente.
<code>#include <iostream> #include <vector> 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<foo> foos; foos.emplace_back(1); foos.emplace_back(2); } </code>
Na minha máquina específica usando meu compilador específico (GCC 4.7), isso imprime o seguinte:
<code>foo(1) foo(2) foo(foo(1)) ~foo(1) ~foo(1) ~foo(2) </code>
No entanto, ao excluir o construtor de cópia (foo(foo const&) = delete;
), a seguinte saída (esperada) é gerada:
<code>foo(1) foo(2) foo(move(foo(1)) ~foo(1) ~foo(2) </code>
Por que é que? Geralmente, a movimentação não seria mais eficiente, ou pelo menos não muito menos eficiente, do que a cópia?
Vale notar queGCC 4.5.1 faz a coisa esperada - isso é uma regressão no GCC 4.7 ou é uma otimização maliciosamente inteligente porque o compilador vê que meu objeto é barato de copiar (mas como ?!)?
Observe também que eu me certifiquei de que issoé causada pela realocação, colocando experimentalmentefoos.reserve(2);
na frente das inserções; isso não causa cópia nem movimento para ser executado.