Home > Net >  vector move operation vs element move operation
vector move operation vs element move operation

Time:05-18

For the following example, why the vector move operation is not triggered? How do I know when I should explicitly use a move operator?

#include <iostream>
#include <vector> 

using namespace std;

class Test {
  public: 
    Test() {
      std::cout << " default " << std::endl;
        
    }
    
    Test(const Test& o) {
        std::cout << " copy ctor " << std::endl;
    }
    
    Test& operator=(const Test& o) {
        std::cout << " copy assign " << std::endl;
        return *this;
    }
    
    Test(Test&& o) {
        std::cout << " move ctor" << std::endl;
    }
    
    Test& operator=(Test&& o) {
        std::cout << " move assign " << std::endl;
        return *this;
    }
};

int main()
{
  std::cout << " vector: " << std::endl;
  std::vector<Test> p;
  p = {Test()}; // expect vector move here since the RHS is temporary. 
  std::cout << std::endl;
   
  std::cout << " single value " << std::endl;
  Test tt;
  tt = Test();
}

Output:

 vector: 
 default 
 copy ctor 

 single value 
 default 
 default 
 move assign 

I was under the impression that when we assign a temporary variable to a lvalue (the single value case in the example), it would trigger a move operation if it exists. Seems that I was wrong and my understanding was overly simplified, I need to carefully check case by case to ensure there's no redundant copy.

CodePudding user response:

std::vector has an assignment operator that takes an std::initializer_list:

vector& operator= (initializer_list<value_type> il);

So when you wrote p = {Test()}; you're actually using the above assignment operator.

Now why a call to the copy constructor is made can be understood from dcl.init.list, which states:

An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated a temporary array of N elements of type const E, where N is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list, and the std::initializer_list object is constructed to refer to that array.

  •  Tags:  
  • c
  • Related