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?
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>);
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
Just this
template<typename Type, typename... T>
using areTypeT = and_<std::is_same<T, Type>...>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With