0

Suppose there is a copy--and-move-constructible (and assignable) object, such as std::vector<int>. A class of mine will accept on such object and store it as a member:

class A
{
public:
  void SetVector(const std::vector<int>& v) { v_ = v; }

private:
  std::vector<int> v_;
};

This will make a copy of the vector given by the user. This is classical C++ approach to pass arguments to a function)

Now, suppose the user would be happy with moving his/her vector into an object of type A. This will avoid a copy. For that we need a member function that takes an r-value reference:

class A
{
public:
  void SetVector(const std::vector<int>& v) { v_ = v; }
  void SetVector(std::vector<int>&& v) { v_ = std::move(v); }

private:
  std::vector<int> v_;
};

Now the user has the choice: the vector can be copied into the object, or moved, in which case the original vector is reset (on in whatever state the moved object is after being moved).

On the other hand, we had to write two separate member functions to give the user this choice. When we have tons of similar functions, the burden can be problematic.

There seems to be a third possibility:

class A
{
public:
  void SetVector(std::vector<int> v) { v_ = std::move(v); }

private:
  std::vector<int> v_;
};

This way, the user can provide the vector by l-value reference, in which case the vector is copied, or by r-value reference, in which case it is moved.


Are there drawbacks to this strategy?

Is there perhaps some corner case I'm not considering?

The only difference I see is that with the third way (pass by value) there is always one more move operation (either a copy and a move or two moves). I suppose there is not much the compiler can do to optimize one move away. Assuming I'm happy to pay the price of a move in order to have just one version of the function, is this pass-by-value approach a good idea?

Spiros
  • 2,156
  • 2
  • 23
  • 42
  • [Howard Hinnant's talk](https://youtu.be/vLinb2fgkHk?t=2507) covers this quite well. – Passer By Aug 23 '18 at 08:48
  • This is not a duplicate of the question, @lubgr. Read the question carefully and look at the answers provided in the other question. Here one could use perfect forwarding to eliminate the need of having two functions and giving the caller choice whether he want's to copy the object or move it. – ProXicT Aug 23 '18 at 08:56
  • @ProXicT I don't see what could be said to answer this question that Vittorio Romeo's answer in the linked duplicate doesn't cover. Can you be specific? – Yakk - Adam Nevraumont Aug 23 '18 at 13:14
  • @Yakk-AdamNevraumont Ah, sorry, you are right, I missed that part of the answer. Also, I was looking more on the accepted answer :-) – ProXicT Aug 23 '18 at 13:16
  • As the author of this question, I confirm this is a duplicate. I overlooked the existing question. – Spiros Aug 23 '18 at 14:49

0 Answers0