在 C++ 中,使用参数包作为初始化列表是不好的做法吗?
In C++, is it bad practice to use a parameter pack as an initializer list?
我目前正在试验可变参数模板,因为我正在尝试为我正在处理的项目使用可变参数 class 模板。我希望 class 接受一个整数列表,该列表将用于创建 class 的其他元素。最初,我使用模板构造函数来获取整数数组。但是,我 运行 链接代码时遇到问题。我想出了另一种方法来解决我的问题,使用可变 class 模板来获取整数列表,但我很好奇这段代码是否被认为是糟糕的 c++(我有一段时间没有写过 C++,这感觉非常骇人听闻)。无论如何,这是我编写的测试代码,它按预期编译和工作:
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
这个解决方案有什么问题吗?我一直在网上搜索,似乎没有人以这种方式使用可变参数模板。
在此先感谢您的输入。
唯一的问题是包可以为空,但数组不能。所以在你的例子中,testClass<> c;
不会编译。
要么专门化您的 class,以便仅定义具有非零数量参数的实例,要么在数组中提供占位符元素:
int arr[]{ 0, structure... };
您的解决方案没有任何问题或问题,只是权衡取舍。使用您的解决方案,您可以立即初始化阵列,使其具有最佳性能。使用 std::initializer_list
解决方案,他们必须默认数组的成员,然后复制更多的工作。
另一方面,这意味着您只能在编译时构造对象,而 std::initializer_list
版本可以在 运行 时初始化。
另一个问题是将它们存储在容器中。您不能在 std::vector
中存储不同的 testClass
,因为不同的模板参数意味着它们是不同的类型,而 vector 仅存储单个元素类型。如果你拿了一个 std::initializer_list
那么 testClass
就不是一个模板,你可以在同一个 vector
.
中存储不同的模板
看你想要什么。
I want the class to accept a list of integers which will be used to create other elements of the class
您没有 class 接受整数列表。您拥有的是一个可以用整数列表实例化的模板。这是一个很大的不同。如果你用不同的整数实例化模板,你会得到不同的类型。例如 testClass<1,2>
和 testClass<1,2,3>
是两种不同的类型,它们几乎没有共同点(实际上只是同一个模板的实例化)。如果这是你想要的,你的方法是可以的。
我目前正在试验可变参数模板,因为我正在尝试为我正在处理的项目使用可变参数 class 模板。我希望 class 接受一个整数列表,该列表将用于创建 class 的其他元素。最初,我使用模板构造函数来获取整数数组。但是,我 运行 链接代码时遇到问题。我想出了另一种方法来解决我的问题,使用可变 class 模板来获取整数列表,但我很好奇这段代码是否被认为是糟糕的 c++(我有一段时间没有写过 C++,这感觉非常骇人听闻)。无论如何,这是我编写的测试代码,它按预期编译和工作:
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
这个解决方案有什么问题吗?我一直在网上搜索,似乎没有人以这种方式使用可变参数模板。
在此先感谢您的输入。
唯一的问题是包可以为空,但数组不能。所以在你的例子中,testClass<> c;
不会编译。
要么专门化您的 class,以便仅定义具有非零数量参数的实例,要么在数组中提供占位符元素:
int arr[]{ 0, structure... };
您的解决方案没有任何问题或问题,只是权衡取舍。使用您的解决方案,您可以立即初始化阵列,使其具有最佳性能。使用 std::initializer_list
解决方案,他们必须默认数组的成员,然后复制更多的工作。
另一方面,这意味着您只能在编译时构造对象,而 std::initializer_list
版本可以在 运行 时初始化。
另一个问题是将它们存储在容器中。您不能在 std::vector
中存储不同的 testClass
,因为不同的模板参数意味着它们是不同的类型,而 vector 仅存储单个元素类型。如果你拿了一个 std::initializer_list
那么 testClass
就不是一个模板,你可以在同一个 vector
.
看你想要什么。
I want the class to accept a list of integers which will be used to create other elements of the class
您没有 class 接受整数列表。您拥有的是一个可以用整数列表实例化的模板。这是一个很大的不同。如果你用不同的整数实例化模板,你会得到不同的类型。例如 testClass<1,2>
和 testClass<1,2,3>
是两种不同的类型,它们几乎没有共同点(实际上只是同一个模板的实例化)。如果这是你想要的,你的方法是可以的。