检查所有类型 T 的参数包

Check a parameter pack for all of type T

Jonathan Wakely 的 to the question 提供了一种简单的方法来检查参数包中扩展的所有变量是否属于同一类型 - 例如:

#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 这样的模板。

我的第一次尝试是 "Parameter pack 'T' must be at the end of the template parameter list"。我最近的尝试可以编译,但如果我使用它,则会出现替换失败:

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

我怎样才能完成这项工作?

您的语法有点偏离,您不需要两个单独的模板声明,该语法用于在 class:

之外定义成员模板
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

就是这个

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

C++17 定义了一个名为 std::conjunctionand_ 版本,定义在标准库的 <type_traits> 头文件中。

template <typename T, typename ...Ts>
using areT = std::conjunction<std::is_same<T,Ts>...>;

static_assert(areT<int,int,int,int>::value);

还有一个名为 std::conjunction_vstd::conjunction 版本,它提供其实例化的 value 数据成员。所以你也可以自己定义一个 areT_v C++14 变量模板:

template <typename T, typename ...Ts>
inline constexpr bool areT_v = std::conjunction_v<std::is_same<T,Ts>...>;

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

假设空包会导致错误值。