创建类似这样的类时:
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}
编译)。
有没有更好的方法来实现这一目标?
答案 0 :(得分:0)
怎么样:
template <typename String, typename VectorInt>
Test(String &&s1, String &&s2, VectorInt &&v,
typename std::enable_if<std::is_same<typename std::decay<String>::type,std::string>::value &&
std::is_same<typename std::decay<VectorInt>::type,std::vector<int>>::value>::type * = nullptr) :
s1_(std::forward<String>(s1)), s2_(std::forward<String>(s2)),
v_(std::forward<VectorInt>(v))
{}