繁体   English   中英

是否可以在模板类中编写一个静态可变参数模板函数,该函数可以接受N个类型为T的参数?

[英]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向量是唯一可以具有叉积的对象是愚蠢的。 我敢肯定,如果我可以编写此函数,就可以做到。 另外,我是一个独立游戏开发商,该功能在我脑子里玩的一些游戏中对我来说很有用。

奖励材料:使用可变参数模板会给我带来另一个问题。 一旦将所有这些FooArrays放入Weirdness()函数中,我就必须进行计算,要求(对于返回变量中的每个成员)访问每个传递参数的两个不同成员。 那么也许这是一个糟糕的设计选择? 我正在考虑使用递归私有静态可变参数模板函数来填充大小为N *(N-1)的T的静态数组。 现有功能不允许我使用这种小提琴。 但是,该设计位完全是开放式的,也许需要在一个更加开放式的友好平台上提出另一个问题。 :)

再添加一个静态断言:

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.");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM