Check a parameter pack for all of type T

大城市里の小女人 提交于 2020-01-12 14:02:45

问题


Jonathan Wakely's answer to the question Type trait to check that all types in a parameter pack are copy constructible gives a simple(ish) way to check if all of the variables expanded in a parameter pack are of the same type - eg:

#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>...>;

I can't work out how to extend this, to write a template like areTypeT, for example.

My first attempts stumbled on "Parameter pack 'T' must be at the end of the template parameter list". My more recent attempt compiles, but if I use it then I get substitution failures:

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

How can I make this work?


回答1:


Your syntax is just off a bit, you don't need two separate template declarations, that syntax is for defining member templates out-of-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




回答2:


C++17 defines a version of and_ called std::conjunction defined in the <type_traits> header from the standard library.

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

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

There is also a version of std::conjunction called std::conjunction_v which provides the value data member of its instantiation. So too you could define an areT_v C++14 variable template yourself:

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



回答3:


Just this

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



回答4:


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

Assuming that an empty pack would result in a false value.



来源:https://stackoverflow.com/questions/31533469/check-a-parameter-pack-for-all-of-type-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!