创建这样的类时:
class Test {
public:
...
private:
string s1_;
string s2_;
vector<int> v_;
};
声明一个接受两个字符串和一个向量的构造函数的最佳方法是什么?而且,更具体地说,您如何处理左值和右值引用?
我看到以下三个选项:
创建 lvref 和 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)} { ... }
优点:每一种可能性都得到了有效处理。
缺点:需要大量代码来处理每种组合,并且可能容易出错。
始终复制和移动参数:
Test(string s1, string s2, vector<int> v) : s1_{move(s1)}, s2_{move(s2)}, v_{move(v)} { ... }
优点:只有一个演员。
缺点:效率不高,因为移动并不意味着免费。
使用“通用参考”:
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)} { ... }
优点:一个能有效处理所有事情的演员。
缺点:没有真正的意义。什么是 s1、s2 和 v?可能更容易出错(例如
Test error{1,2,3}
编译)。
有没有更好的方法来实现这一目标?