检查所有类型T的参数包

时间:2015-07-21 08:02:34

标签: c++ c++11 variadic-templates

Jonathan Wakely对问题answerType trait to check that all types in a parameter pack are copy constructible提供了一种简单(ish)方法来检查参数包中扩展的所有变量是否属于同一类型 - 例如:

#include <type_traits>

namespace detail {
    enum class enabler {};
}

template <bool Condition>
using EnableIf =
    typename std::enable_if<Condition, detail::enabler>::type;

template<typename... Conds>
struct and_ : std::true_type {};

template<typename Cond, typename... Conds>
struct and_<Cond, Conds...>
        : std::conditional<Cond::value, and_<Conds...>,
        std::false_type>::type {};

template<typename... T>
using areInts = and_<std::is_same<T,int>...>;

template<typename... T>
using areMySpecificClass = and_<std::is_same<T,MySpecificClass>...>;

我无法弄清楚如何扩展它,例如编写像areTypeT这样的模板。

我的第一次尝试偶然发现“参数包'T'必须位于模板参数列表的末尾”。我最近的尝试编译,但如果我使用它然后我得到替换失败:

template<typename Target>
template<typename... T1>
using areT = and_<std::is_same<T1,Target>...>;

我该如何做到这一点?

4 个答案:

答案 0 :(得分:5)

您的语法稍微偏离,您不需要两个单独的模板声明,该语法用于定义类外的成员模板:

template<typename Target, typename... Ts>
using areT = and_<std::is_same<Ts,Target>...>;

static_assert(areT<int,int,int,int>::value,"wat");
static_assert(!areT<int,float,int,int>::value,"wat");

Demo

答案 1 :(得分:2)

就是这个

template<typename Type, typename... T>
using areTypeT = and_<std::is_same<T, Type>...>;

答案 2 :(得分:2)

C ++ 17定义了and_的{​​{1}}版本,该版本在标准库的std::conjunction标头中定义。

<type_traits>

还有template <typename T, typename ...Ts> using areT = std::conjunction<std::is_same<T,Ts>...>; static_assert(areT<int,int,int,int>::value); 的{​​{1}}版本,它提供了其实例化的std::conjunction数据成员。因此,您也可以自己定义std::conjunction_v C ++ 14变量模板:

value

答案 3 :(得分:0)

template <typename ... Types>
constexpr bool all_same_v = sizeof...(Types) ? (std::is_same_v<std::tuple_element_t<0, std::tuple<Types...>>, Types> && ...) : false;

假设一个空包将导致错误的值。