0

在一个混合了 CRTP、可变参数模板、元编程和运算符重载的类中,我想比较两个可变参数 unsigned int 模板参数以进行一些静态断言。我认为辅助结构将是做到这一点的好方法,但我不知道该怎么做。我想到了一些形式:

template<unsigned int... TDIM, unsigned int... TDIM0> struct HelperCheckDimensions
{
    static const bool ok = /* SOMETHING */
};

whereTDIMTDIM0是我要比较的两个参数。它允许我输入:

static_assert(HelperCheckDimensions<TDIM..., TDIM0...>::ok, "ERROR : Dimensions are different !");

我希望结果只有在sizeof...(TDIM)==sizeof...(TDIM0)AND时才为真TDIM[0] == TDIM0[0], TDIM[1] == TDIM0[1], ..., TDIM[n] == TDIM0[n]

怎么做 ?

非常感谢你。

4

3 回答 3

5

我会说这种形式的类 variadic-template 没有意义:

template<unsigned int... TDIM, unsigned int... TDIM0> 
struct HelperCheckDimensions
{
    //..
};

这没有意义,因为如果我写这个:

HelperCheckDimensions<1,2,3,4,5,6> z;

那么应该是什么TDIMTDIM0编译器应该如何对参数进行分区?

它是否正确:

TDIM = (1,2)
TDIM0 = (3,4,5,6)

或者这是正确的:

TDIM = (1)
TDIM0 = (2,3,4,5,6)

或这个:

TDIM = (1,2,3,4)
TDIM0 = (5,6)

希望这有助于为什么它没有意义。


从您的评论中:

很好的一点!但我的问题仍然悬而未决......也许某种形式的东西template<unsigned int... TDIM, typename TFAKE, unsigned int... TDIM0>会起作用?什么是最好的解决方案?

那么标准不允许此表单的模板定义:

template<unsigned int... TDIM, typename TFAKE, unsigned int... TDIM0>

我不知道标准为什么不允许它,即使它对我来说是有意义的,至少在这种情况下(也许它给语言增加了不值得的复杂性)。根据标准,模板参数包必须是模板定义的最后一个参数。

如果您在 GCC 中编译上述代码,则会出现以下错误:

错误:参数包“TDIM”必须位于模板参数列表的末尾

希望有帮助。

于 2012-08-10T05:52:31.070 回答
1

初级类模板不能有两个参数包,你需要使用一些包包装器

template<unsigned int...T> struct intPack;
template<typename T, typename Y> struct HelperCheckDimensions;

template<unsigned int lhs, unsigned int...T, unsigned int rhs, unsigned int...Y> struct HelperCheckDimensions<intPack<lhs,T...>, intPack<rhs, Y...>>
{
static const bool value = lhs==rhs && HelperCheckDimensions<intPack<T...>, intPack<Y...>>::value;
};
template<unsigned int lhs, unsigned int rhs> struct HelperCheckDimensions<intPack<lhs>, intPack<rhs>>
{
static const bool value = lhs==rhs;
};

测试: http: //liveworkspace.org/code/200e10548f3fc589f39401ca0b22e7c8

于 2012-08-10T06:10:35.840 回答
1

假设您的主模板如下所示:

template <int ...> struct Foo;

您现在可以制作一个Foo比较器:

template <typename, typename> struct FooCmp : std::false_type { };

template <int A, int B, int ...As, int ...Bs>
struct FooCmp<Foo<A, As...>, Foo<B, Bs...>>
: std::integral_constant<bool, A == B && FooCmp<Foo<As...>, Foo<Bs...>>::value>
{ };

template <> struct FooCmp<Foo<>, Foo<>> : std::true_type { };

用法:

typedef Foo<1, 3, 4> F1;
typedef Foo<9, 5, 1> F2;

template <typename S, typename T>
std::enable_if<FooCmp<S, T>::value> do_magic(S s, T t) { /* ... */ }

do_magic(F1{}, F2{});
于 2012-08-10T06:13:17.917 回答