是否可以在模板类中编写一个静态可变参数模板函数,该函数能够接受 T 类型的 N 个参数?
Is it possible to write a static variadic template function, in a template class, that's able to take N parameters of type T?
我在编写以下变量函数时遇到问题:
1) 取适当类型FooArray<T, N>
和的适当数量的参数N-1 (N always > 2)
2) 允许我用我需要的精细方式与他们玩耍。
因此,给定以下模板类:
template <typename T, unsigned int N>
class FooArray{
private:
T m_data[N];
};
以及以下静态可变模板函数声明:
template <typename T, unsigned int N>
class FooArray{
public:
template <typename ... ArgT>
static FooArray<T, N> Weirdness(FooArray<T, N> _arg1, ArgT ... _args);
private:
T m_data[N];
};
以及该类中的相关实现:
template <typename T, unsigned int N>
template <typename ... ArgT>
FooArray<T, N>
FooArray<T, N>::Weirdness(T _arg1, ArgT ... _args)
{
static_assert(N > 2, "Not enough Ns for Weirdness.");
static_assert(N - 2 == sizeof... (_args), "Incorrect parameter number.");
FooArray<T, N> result;
// ...
// Put parameters into table of size N * (N-1) maybe?
// Do stuff with that to determine result.
// ...
return result;
}
我希望给定的代码(或类似的代码)在标记的地方返回错误,并且在标记的位置也有效。
int main()
{
FooArray<int, 2> test2parameter;
FooArray<int, 3> test3param1, test3param2;
FooArray<int, 4> test4p1, test4p2, test4p3;
//FooArray<int, 2>::Weirdness(test2parameter); // Should error(and does), not enough N's.
//FooArray<int, 3>::Weirdness(); // Should error(and does), requires 2 parameters.
//FooArray<int, 3>::Weirdness(test2parameter); // Should error(and does), requires 2 parameters of type FooArray<int, 3>.
FooArray<int, 3>::Weirdness(test3param1, test2parameter); // Should error(currently doesn't), all parameters should be FooArray<int, 3>.
FooArray<int, 3>::Weirdness(test3param1, test3param2); // Valid.
//FooArray<int, 4>::Weirdness(); // Should error (and does), requires 3 parameters.
//FooArray<int, 4>::Weirdness(test4p1, test4p2); // Should error (and currently does), requires 3 parameters.
FooArray<int, 4>::Weirdness(test4p1, test4p2, test3param1); // Should error (currently doesn't), all parameters should be FooArray<int, 4>.
FooArray<int, 4>::Weirdness(test4p1, test4p2, test4p3); // Valid.
//FooArray<int, 12>::Weirdness(test12p1, test12p2, test12p3, test12p4, test12p5, test12p6, test12p7, test12p8, test12p9, test12p10, test12p11); // Will be a valid case.
return 0;
}
回复:第一个问题,我有90%的回答。一旦编译器因为向函数传递了不正确的参数类型而向我抛出错误,问题就得到了回答。
谢谢你抽出时间。(说真的,如果你时间不够或正试图解决自己的问题,现在就停止阅读)
回复:你为什么要这么做?我正试图写一个N维向量(几何)叉积函数,因为我认为数学家认为3D向量是唯一可以有叉积的向量是愚蠢的。如果我能写这个函数,我确信我能做到。另外,我是一名独立游戏开发商,这个功能在我脑海中的一些游戏中有着有趣的用途。
额外的材料:我有另一个使用可变模板给我带来的问题。一旦我在Weirdness()函数中拥有了所有这些FooArrays,我就必须进行计算,要求(返回变量中的每个成员)访问每个传递参数的两个不同成员。所以,也许这是一个糟糕的设计选择?我正在考虑一个递归的私有静态可变模板函数来填充大小为N*(N-1)的Ts的静态数组。现有的功能不允许我需要这种精细的小提琴。不过,这个设计部分都是非常开放的,也许可以在一个更开放的问题友好的平台上提出另一个问题。:)
再添加一个静态断言:
static_assert(are_same<FooArray<T, N>, ArgT...>::value, "Types do not all match");
并实现are_same<>
:
template <typename A1, typename A2, typename ... Rest>
struct are_same
{
enum { value = std::is_same<A1, A2>::value && are_same<A2, Rest...>::value };
};
template <typename A1, typename A2>
struct are_same<A1, A2>
{
enum { value = std::is_same<A1, A2>::value };
};
我更喜欢一个更简单的函数声明,并使用John Zwinck的方法来确保参数类型都是正确的。
template <typename T, unsigned int N>
template <typename ... ArgT>
FooArray<T, N>
FooArray<T, N>::Weirdness(ArgT ... _args)
{
static_assert(are_same<FooArray<T, N>, ArgT...>::value, "Types do not all match");
static_assert(N > 2, "Not enough Ns for Weirdness.");
static_assert(N - 1 == sizeof... (_args), "Incorrect parameter number.");
相关文章:
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类