Search code examples
c++move

Constructor with move and copy semantics


I need to write a constructor for my class which takes two std::vector as arguments. These vectors have to be copied in private members, and I'd like to use the move semantics when my users pass a temporary or an rvalue reference and the copy semantics otherwise. This is a common issue which leads to write a copy and a move constructor to handle construction starting from an object of the same class. But in my case I am constructing starting from two different parameters (vectors), each of which can either be an lvalue or an rvalue; so I must handle four different cases:

MyClass(const std:vector<float> &v1, const std::vector<float> &v2):
  _v1(v1), _v2(v2) {};
MyClass(const std:vector<float> &v1, std::vector<float> &&v2):
  _v1(v1), _v2(std::move(v2)) {};
MyClass(std:vector<float> &&v1, const std::vector<float> &v2):
  _v1(std::move(v1)), _v2(v2) {};
MyClass(std:vector<float> &&v1, std::vector<float> &&v2): 
  _v1(std::move(v1)), _v2(std::move(v2)) {};

each of which requires a small variation of the same constructor logic, with an unpleasant prolification of similar code snippets. Things would get exponentially worse if other vector parameter is added. Which is the best practice to handle this situation? Thanks.


Solution

  • You can simply pass by value:

    MyClass(std::vector<float> v1, std::vector<float> v2)
        : _v1(std::move(v1)), _v2(std::move(v2)) {}
    

    It comes at the cost of one extra move contructor call per parameter (regardless of whether an argument is lvalue or rvalue), which may or may not be optimized away.