I have some strange behavior on std::vector with adding rvalues:
#include <iostream>
#include <vector>
class A {
public:
A():i_{5}{std::cout << "default" << std::endl;}
A(const A &data) { std::cout << "copied!" << std::endl; }
A(A &&data) { std::cout << "moved " << std::endl; }
int i_;
};
int main(int argc, char *argv[]) {
std::vector<A> datavec;
datavec.push_back(A{});
datavec.push_back(A{});
return 0;
}
output is:
default
moved
default
moved
copied!
So vector still creates copies of A, the more pushes I do - the more copies I get. However, if I replace move constructor with default one A(A &&data) = default; or delete copy constructor with A(const A &data) = delete; I get right result where no copies are made. I also have no copies if I first call datavec.reserve with enough size. I use gcc version 5.4.0 with no specific arguments
g++ -std=c++11 -o main ../main.cpp
Have you got any thoughts on why vector makes copies of obvious rvalues? I hope it is not some bug of STL
The std::vector
is copying your elements during internal buffer reallocation. It is choosing to copy instead of moving because your move constructor is not marked noexcept
. Marking it...
A(A &&) noexcept { std::cout << "moved " << std::endl; }
...will fix the issue.
Telling the compiler that your move constructor will not throw allows std::vector
's implementation to move during internal reallocation, fulfilling the exception guarantees demanded by the C++ Standard.
Alternatively, you can std::vector::reserve
your container in advance to prevent the growth of the internal buffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With