在C ++ 11中声明多个参数构造函数的最佳方法是什么

时间:2013-04-16 14:10:53

标签: c++ c++11 constructor move-semantics rvalue-reference

创建类似这样的类时:

class Test {
 public:
   ...

private:
   string s1_;
   string s2_;
   vector<int> v_;
};

声明构造函数接受两个字符串和一个向量的最佳方法是什么?而且,更具体地说,您如何处理左值和左值参考?

我看到以下三个选项:

  1. 创建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)}
       {
          ...
       }
    

    优点:每种可能性都得到有效处理。

    缺点:需要大量代码来处理每个组合,并且可能容易出错。

  2. 始终复制并移动参数:

       Test(string s1, string s2, vector<int> v) :
          s1_{move(s1)}, s2_{move(s2)}, v_{move(v)}
       {
          ...
       }
    

    优点:只有一个人。

    缺点:效率不高,因为移动并不意味着免费。

  3. 使用“通用参考”:

       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}编译)。

  4. 有没有更好的方法来实现这一目标?

1 个答案:

答案 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))
{}