[英]Is it possible to write a static variadic template function, in a template class, that's able to take N parameters of type T?
I'm having trouble writing the variadic function that: 我在编写可变参数函数时遇到了麻烦:
1) takes the appropriate number of parameters N-1 (N always > 2)
of the appropriate type FooArray<T, N>
and 1)采取适当数量的FooArray<T, N>
和适当类型的参数N-1 (N always > 2)
2) allows me to play with them in the fiddly way I need to. 2)让我以自己需要的方式与他们一起玩。
So, given the following template class: 因此,给定以下模板类:
template <typename T, unsigned int N>
class FooArray{
private:
T m_data[N];
};
and the following static variadic template function declaration: 以及以下静态可变参数模板函数声明:
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];
};
and associated implementation in that class: 以及该类中的相关实现:
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;
}
I want to have the given code (or something like it) return me errors at the marked places and be valid in the marked places too. 我想要给定的代码(或类似的代码)在标记的地方返回错误,并且在标记的地方也有效。
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;
}
Re: the initial question, I'm 90% there. 回复:第一个问题,我在那里90%。 Once I have the compiler throwing errors at me for passing the function an incorrect parameter type, the question is answered. 一旦我让编译器因向函数传递错误的参数类型而向我抛出错误,就可以回答问题。
Thank you for your time. 感谢您的时间。 (Seriously, stop reading now if you're short on time or are trying to solve your own problem) (严重的是,如果您时间有限或正试图解决自己的问题,请立即停止阅读)
Re: Why would you want to do this? 回复:你为什么要这样做? I am trying to write an N-Dimensional vector (geometry) cross product function, because I think mathematicians are silly for thinking 3D vectors are the only ones that can have a cross product. 我试图编写一个N维向量(几何)叉积函数,因为我认为数学家认为3D向量是唯一可以具有叉积的对象是愚蠢的。 I'm certain I can do it if I can write this function. 我敢肯定,如果我可以编写此函数,就可以做到。 Plus, I'm an indie game developer, this function has interesting uses for me in a handful of games I've got kicking around in my brain. 另外,我是一个独立游戏开发商,该功能在我脑子里玩的一些游戏中对我来说很有用。
Bonus material: I have another problem that using variadic templates creates for me. 奖励材料:使用可变参数模板会给我带来另一个问题。 Once I have all these FooArrays inside my Weirdness() function, I have to do a calculation that requires (for every member in the return variable) access to two different members of every passed parameter. 一旦将所有这些FooArrays放入Weirdness()函数中,我就必须进行计算,要求(对于返回变量中的每个成员)访问每个传递参数的两个不同成员。 So perhaps this is a poor design choice? 那么也许这是一个糟糕的设计选择? I'm considering a recursive private static variadic template function to perhaps populate a static array of Ts of size N*(N-1). 我正在考虑使用递归私有静态可变参数模板函数来填充大小为N *(N-1)的T的静态数组。 The existing function doesn't allow this fine fiddle I require. 现有功能不允许我使用这种小提琴。 This design bit is all very open ended though and perhaps warrants another question on a more open-ended-question friendly platform. 但是,该设计位完全是开放式的,也许需要在一个更加开放式的友好平台上提出另一个问题。 :) :)
Add one more static assertion: 再添加一个静态断言:
static_assert(are_same<FooArray<T, N>, ArgT...>::value, "Types do not all match");
And implement are_same<>
: 并实现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 };
};
I would prefer a simpler function declaration and using John Zwinck's method to ensure the parameter types are all correct. 我希望使用更简单的函数声明,并使用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.");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.