When creating a class like this one:
class Test {
 public:
   ...
private:
   string s1_;
   string s2_;
   vector<int> v_;
};
What is the best way to declare a constructor accepting two strings and a vector? And, more specifically, how do you handle lvalue and rvalue references?
I see the three following options:
- Create every combination of lvref and rvref: - Test(const string& s1, const string& s2, const vector<int>& v) : s1_{s1}, s2_{s2}, v_{v} { ... } Test(const string& s1, const string& s2, vector<int>&& v) : s1_{s1}, s2_{s2}, v_{move(v)} { ... } Test(const string& s1, string&& s2, const vector<int>& v) : s1_{s1}, s2_{move(s2)}, v_{v} { ... } Test(const string& s1, string&& s2, vector<int>&& v) : s1_{s1}, s2_{move(s2)}, v_{move(v)} { ... } Test(string&& s1, const string& s2, const vector<int>& v) : s1_{move(s1)}, s2_{s2}, v_{v} { ... } Test(string&& s1, const string& s2, vector<int>&& v) : s1_{move(s1)}, s2_{s2}, v_{move(v)} { ... } Test(string&& s1, string&& s2, const vector<int>& v) : s1_{move(s1)}, s2_{move(s2)}, v_{v} { ... } Test(string&& s1, string&& s2, vector<int>&& v) : s1_{move(s1)}, s2_{move(s2)}, v_{move(v)} { ... }- Pros: Every possibility handled efficiently. - Cons: Requires a lot of code to handle every combination and might be error prone. 
- Always copy and move the arguments: - Test(string s1, string s2, vector<int> v) : s1_{move(s1)}, s2_{move(s2)}, v_{move(v)} { ... }- Pros: Only one ctor. - Cons: Not as efficient because move does not mean free. 
- Use "universal references": - template <typename S1, typename S2, typename V> Test(S1&& s1, S2&& s2, V&& v) : s1_{forward<S1>(s1)}, s2_{forward<S2>(s2)}, v_{forward<V>(v)} { ... }- Pros: One ctor that handles everything efficiently. - Cons: Not really meaningful. What are s1, s2 and v? Can be even more error prone (e.g. - Test error{1,2,3}compiles).
Is there a better way to achieve that?
 
     
    