在C ++中,将参数包用作初始化列表是一种不好的做法吗?

时间:2019-12-12 21:04:14

标签: c++ class variadic-templates parameter-expansion

我正在尝试使用可变参数模板,因为我正尝试为正在处理的项目使用可变参数类模板。我希望该类接受整数列表,这些整数将用于创建该类的其他元素。最初,我使用模板构造函数来获取整数数组。但是,我在链接代码时遇到了问题。我想出了一种使用可变参量类模板来获取整数列表的方法来解决我的问题,但是我很好奇这个代码是否被认为是不好的c ++(我已经有一段时间没有写C ++了,感觉很hacky)。无论如何,这是我编写的测试代码,可以按预期编译和运行:

template<int...structure>
class testClass{

public:
testClass(){
      std::size_t size = sizeof...(structure);
      std::cout << size << '\n';
      int arr[]{ structure... };
      for (int i = 0; i < size; i++) 
          std::cout << arr[i] << '\n';
   }


};

int main() {
   testClass<1, 2, 3> c;
}

如预期的那样,代码输出:

3
1
2
3

此解决方案有什么问题吗?我一直在网上搜索,似乎没人以这种方式使用可变参数模板。

谢谢您的输入。

3 个答案:

答案 0 :(得分:5)

您的解决方案没有任何错误或棘手,这只是一个权衡。使用您的解决方案,您可以立即初始化数组,使其具有最佳性能。使用std::initializer_list解决方案,他们必须默认数组的成员,然后进行复制,这是更多工作。

另一方面,这意味着您只能在编译时构造对象,而std::initializer_list版本可以在运行时初始化。

另一个问题是将它们存储在容器中。您不能在testClass中存储不同的std::vector,因为不同的模板参数意味着它们是不同的类型,向量仅存储单个元素类型。如果您使用了std::initializer_list,则testClass不会是模板,您可以将不同的模板存储在同一vector中。

答案 1 :(得分:3)

唯一的问题是一个包可以为空,但不能为数组。因此,在您的示例中,testClass<> c;无法编译。

要么专门研究类,要么仅定义具有非零数量参数的实例化,或者在数组中提供占位符元素:

int arr[]{ 0, structure... };

答案 2 :(得分:3)

取决于您的需求。

  

我希望该类接受一个整数列表,这些整数将用于创建该类的其他元素

您没有一个可以接受整数列表的类。您拥有的是一个可以用整数列表实例化的模板。那是很大的不同。如果使用不同的整数实例化模板,则会得到不同的类型。例如,testClass<1,2>testClass<1,2,3>是两种不同的类型,它们几乎没有共同点(实际上只是相同模板的实例化而已)。如果这是您想要的方法,那就可以了。