1

考虑以下示例:

#include <iostream>
#include <type_traits>

template <typename Type>
struct Something
{
    template <typename OtherType> 
    static constexpr bool same()
    {return std::is_same<Type, OtherType>::value;}
};

template <class Type>
struct Example
{
    static_assert(Type::template same<double>(), "ERROR");
};

int main()
{
    Example<Something<double>> example;
    return 0;
}

通过执行函数static_assert检查传递的类型是否满足某些条件。same()

现在考虑可以将多个传递TypesExample

#include <iostream>
#include <type_traits>

template <typename Type>
struct Something
{
    template <typename OtherType> 
    static constexpr bool same()
    {return std::is_same<Type, OtherType>::value;}
};

template <class... Types>
struct Example
{
    static_assert(/* SOMETHING */, "ERROR");
};

int main()
{
    Example<Something<double>> example;
    return 0;
}

是否有一种有效的语法,而不是SOMETHING检查条件是否在所有类型上都得到验证(没有一堆辅助函数:我知道可以通过这种方式完成,但我想知道是否有另一种方式(比如在某处使用简单的解包。 ..))

4

2 回答 2

1

实际上,您对参数包唯一能做的就是将其解包为函数的一组参数。所以不,没有助手就无法做到这一点。

如果你允许辅助函数,有上千种方法可以做到。最明显的是某种logical_and

template<class first, class ...rest>
constexpr bool logical_and(first f, rest... r)
{return bool(f) && logical_and(std::forward<rest>(r)...));}
//                           ^unpack the rest recursively^

template<class last>
constexpr bool logical_and(last l)
{return bool(l);}

template <class... Types>
struct Example
{
    static_assert(logical_and(Something<double>::same<Types>()...), "ERROR");
    //                        ^unpack the results to the function^
};

这是完全未经测试的,可能无法按原样编译

于 2013-07-26T02:36:21.400 回答
0

您可以通过简单地专门化 template Example.

如果在现实世界Example中是一个你不想仅仅为了可变参数而专门化的类, static_assert那么你可以将可变参数封装static_assert 在它自己的模板特化中,并让你的现实世界类继承相应的实例化。这是一个专门的插图Example

#include <iostream>
#include <type_traits>

template <typename Type>
struct Something
{
    template <typename OtherType> 
    static constexpr bool same()
    {return std::is_same<Type, OtherType>::value;}
};

template<class ...Types>
struct Example;

template<>
struct Example<>{};

template<class T>
struct Example<T>
{
    static_assert(T::template same<double>(), "ERROR");
};

template<class First, class ...Rest>
struct Example<First,Rest...> : Example<Rest...>
{
    static_assert(First::template same<double>(), "ERROR");
};

int main()
{
    Example<Something<double>> example0; // OK
    Example<Something<double>,Something<double>> example1; // OK
    Example<Something<int>> example2; // Error
    Example<Something<double>,Something<int>> example3; // Error
    Example<Something<double>,Something<double>,Something<int>> example4; // Error
    Example<Something<double>,Something<int>,Something<double>> example5; // Error
    return 0;
}
于 2013-07-26T11:16:12.557 回答