To demo move semantics, I wrote the following example code, with an implicit constructor from int.
struct C { int i_=0; C() {} C(int i) : i_( i ) {} C( const C& other) :i_(other.i_) { std::cout << "A copy construction was made." << i_<<std::endl; } C& operator=( const C& other) { i_= other.i_ ; std::cout << "A copy assign was made."<< i_<<std::endl; return *this; } C( C&& other ) noexcept :i_( std::move(other.i_)) { std::cout << "A move construction was made." << i_ << std::endl; } C& operator=( C&& other ) noexcept { i_ = std::move(other.i_); std::cout << "A move assign was made." << i_ << std::endl; return *this; } }; And
auto vec2 = std::vector<C>{1,2,3,4,5}; cout << "reversing\n"; std::reverse(vec2.begin(),vec2.end()); With output
A copy construction was made.1 A copy construction was made.2 A copy construction was made.3 A copy construction was made.4 A copy construction was made.5 reversing A move construction was made.1 A move assign was made.5 A move assign was made.1 A move construction was made.2 A move assign was made.4 A move assign was made.2 Now, the reverse shows the 2 two swaps (each using one move assign and two move constructs), but why are the temporary C objects created from the initializer list not possible to move from? I thought I had an initializer list of integers, but I'm now wondering if what I have in between is an initializer list of Cs, which can't be moved from (as its const). Is this a correct interpretation? - What's going on?
std::vector<C>expects anstd::initializer_list<C>so your list of int's is constructed into a temporary list of C and it is that list of C's that is being copied from. At least that is what I reason the code to have to do.std::vector<C>doesn't have constructor which takesstd::initializer_list<int>(but it has one forstd::initializer_list<C>).