Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a variadic is_same?

How can I make a class template that returns whether any of its variadic types are equal to the first type. I want to be able to do this:

is_same<T, A, B, C>::value; // true if T is one of A, B or C 

And if T is equal to any one of those types, its static value member will be true, otherwise false. How can I do this?

like image 876
Me myself and I Avatar asked Jun 10 '13 20:06

Me myself and I


2 Answers

Nice and concise with C++17:

template <class T, class... Ts> struct is_any : std::disjunction<std::is_same<T, Ts>...> {}; 

And the dual:

template <class T, class... Ts> struct are_same : std::conjunction<std::is_same<T, Ts>...> {}; 

A variation that uses fold expressions:

template <class T, class... Ts> struct is_any : std::bool_constant<(std::is_same_v<T, Ts> || ...)> {};  template <class T, class... Ts> struct are_same : std::bool_constant<(std::is_same_v<T, Ts> && ...)> {}; 
like image 192
mavam Avatar answered Sep 21 '22 03:09

mavam


Use template recursion:

template<typename T, typename... Rest> struct is_any : std::false_type {};  template<typename T, typename First> struct is_any<T, First> : std::is_same<T, First> {};  template<typename T, typename First, typename... Rest> struct is_any<T, First, Rest...>     : std::integral_constant<bool, std::is_same<T, First>::value || is_any<T, Rest...>::value> {};  static_assert(is_any<int, char, double, int>::value, "error 1");   // OK static_assert(is_any<int, char, double, short>::value, "error 2"); // error 
like image 26
syam Avatar answered Sep 23 '22 03:09

syam