【问题标题】:In C++, is it bad practice to use a parameter pack as an initializer list?在 C++ 中,使用参数包作为初始化列表是不好的做法吗?
【发布时间】:2020-04-06 07:43:35
【问题描述】:

我目前正在尝试使用可变参数模板,因为我正在尝试将可变参数类模板用于我正在处理的项目。我希望该类接受一个整数列表,该列表将用于创建该类的其他元素。最初,我使用模板构造函数来获取整数数组。但是,我在链接代码时遇到了问题。我想出了另一种方法来解决我的问题,使用可变参数类模板来获取整数列表,但我很好奇这段代码是否被认为是糟糕的 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

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

提前感谢您的意见。

【问题讨论】:

  • 你到底想用那个类做什么?
  • 当构造函数接受一个数组参数时,它是一个运行时参数。在您的示例中,它是编译时示例。在许多情况下,它们是正交的。
  • @Evg 如果 ctor 是 constexpr 则不一定。

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


【解决方案1】:

唯一的问题是一个包可以是空的,但不能是数组。所以在你的例子中,testClass&lt;&gt; c; 不会编译。

要么专门化你的类,以便只定义具有非零参数的实例化,要么在数组中提供一个占位符元素:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      取决于你想要什么。

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

      您没有一个类可以接受整数列表。你所拥有的是一个可以用整数列表实例化的模板。这是一个很大的区别。如果你用不同的整数实例化模板,你会得到不同的类型。例如testClass&lt;1,2&gt;testClass&lt;1,2,3&gt; 是两个几乎没有共同点的不同类型(实际上只是同一个模板的实例化而已)。如果这是您想要的,那么您的方法就可以了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-15
        • 2018-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-26
        相关资源
        最近更新 更多