使用C ++中方法的参数列表

时间:2015-01-12 16:18:52

标签: c++ templates

这就是我想做的事情 - 我有一个带有几个构造函数的A类。我不想在A类中改变任何东西。我想有一个新的B类,A应该是B的一个元素,并且有一个镜像A的构造函数。

class A{
public:
   A(type1 arg1);
   A(type2 arg1, type3 arg2); 
}

我知道我可以做到这一点

class B{
A *a;
public:
   B(type1 arg1) {
      a = new A(arg1);
      //some other stuff here
   }
   B(type2 arg1, type3 arg2) {
      a = new A(arg1, arg2);
      //some other stuff here, same as the first constructor
   }
}

有办法做到这一点吗?

class B{
A *a;
public:
   B(list_of_args) {
      a = new A(list_of_args);
      //some other stuff here
   }
}

我不想扩展A.我只是想找到一种方法来获取传递给B的参数列表并用此调用A的构造函数。 (不改变A)。

3 个答案:

答案 0 :(得分:7)

使用C ++ 11和可变参数模板,简单:

class B {
    A a;

public:
    template <typename... Args>
    B(Args&&... args)
    : a(std::forward<Args>(args)...)
    { }
};

如果没有可变参数模板,您可以为不同数量的参数添加一堆模板构造函数,但它非常难看。如果没有args是引用,那么它不是所以

template <typename A1> 
B(const A1& a1) : a(a1) { }

template <typename A1, typename A2> 
B(const A1& a1, const A2& a2) : a(a1, a2) { }
// etc.

但实际上,您需要单独处理A1&const A1& ...因此您需要2^NN个参数的构造函数。你可以看出为什么人们对C ++ 11感到兴奋。

(请注意,在您的代码中,您有一个类型为A的类成员,但在您的构造函数示例中,您尝试创建A*)。

答案 1 :(得分:0)

创建模板化构造函数并使用可变参数模板参数:

class B
{
public:
   template<typename... ArgTypes>
   B(ArgTypes... list_of_args) : a(list_of_args...)
   {
     //some other stuff here
   }
private:
  A a;
}

Live demo here


正如@ Barry的回答和评论中提到的那样,最好使用ArgTypes&&std::forward来允许仅移动类型和一些效率。 Live demo here

template<typename... ArgTypes>
B(ArgTypes&&... list_of_args) : a(std::forward<ArgTypes>(list_of_args)...)
{
  // do something here
}

答案 2 :(得分:0)

我正在根据您的需求调整Barry的解决方案:

class A{
public:
   A(type1 arg1);
   A(type2 arg1, type3 arg2); 
}



class B{
A *a;
public:
   template <typename... Args>
   B(Args&&... args) {
      a = new A(std::forward<Args>(args)...);
      //some other stuff here
   }
}

另一种方法是声明一个成员方法来代替&#34; //在这里调用其他东西&#34;对于每个B构造函数。

class B{
A *a;
public:
   void initialize(A* a) {
      this->a = a;
      //some other stuff here
   }

   B(type1 arg1) {
      initialize(new A(arg1));
   }

   B(type2 arg1, type3 arg2) {
      initialize(new A(arg1, arg2));
   }
}