1

If I want to define a method like a setter for a std::vector member (or movable object) I can do it like this:

 void set(const std::vector<int>& v) { _v = v; }

But also I need to add

 void set(std::vector<int>&& v) { _v = std::move(v); }

Right? Is it always best to define both in order to handle temporaries that can be move? So all setters will be doubled? Thanks.

cigien
  • 55,661
  • 11
  • 60
  • 99
lucmobz
  • 433
  • 3
  • 8

1 Answers1

4

If you know the type has an efficient move constructor (which std::vector<int> does), then you can just take by value and move from the argument:

void set(std::vector<int> v) { _v = std::move(v); }

That way, when called with an lvalue it will be copied, but when called with an rvalue it will be moved.

Artyer
  • 20,910
  • 3
  • 38
  • 60
  • 1
    This is exactly how clang-tidy told me to do. – 康桓瑋 Jan 29 '21 at 08:25
  • 1
    I heard that's what they do in Google. source: [Chrome Developers](https://youtu.be/UNJrgsQXvCA?t=235) – Kao Jan 29 '21 at 08:43
  • Is that using template forwarding reference is a bad idea here? – 康桓瑋 Jan 29 '21 at 09:18
  • @Artyer: It might still have debate between [pass-by-value-vs-pass-by-rvalue-reference](https://stackoverflow.com/questions/37935393/pass-by-value-vs-pass-by-rvalue-reference) – Jarod42 Jan 29 '21 at 09:53
  • 1
    @康桓瑋: I expose the different possibilities in [my answer](https://stackoverflow.com/a/61601352/2684539) of *"Taking sink parameters by rvalue reference instead of by value to enforce performant usage of interfaces"*. So it improves performance. Readability is questionable though. – Jarod42 Jan 29 '21 at 09:57