How to make a variadic is_same?

is_same_v is not a member of std
std::is_same
c++ compare types
c template check type
std::true_type
type_traits c 17
c++ traits
std::enable_if

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?

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

std::is_same, Otherwise value is false. Commutativity is satisfied, i.e. for any two types T and U , is_same<T, U>  The solutions in C++11 are based on variadic templates. The first one consists in using SFINAE to disable all instantiations of f whose parameters are not of the type std::string. For this, we need to determine two things: the enable_if expression that says that all the types are strings,

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> && ...)> {};

Return type - Part 1, 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  Variadic templates allow any number of template parameters of any type. In this article we see how to use static_assert and explicit templates to define a variadic number of parameters of the SAME type.

In C++17 you have an even nicer solution, using template variables and fold expressions:

template<class T, class... Rest>
inline constexpr bool are_all_same = (std::is_same_v<T, Rest> && ...);

And the usage is also simpler than all other examples:

are_all_same<T, A, B, C>

No ::value, no parentheses!

How to Define a Variadic Number of Arguments of the , It is notunusual to have a template argument which represent a function. which have variadic number of arguments, look at Variadic number of Using std::​is_same< > , the program checks if the return_t is equal to int or  How to Define A Variadic Number of Arguments of the Same Type – Part 3 Published February 5, 2019 - 0 Comments We’re going further yet into the topic of how to make a variadic pack of template arguments of the same type.

Something like this. First, a small metaprogramming library, because it adds like 2 lines to do it generically:

template<template<typename,typename>class checker, typename... Ts>
struct is_any_to_first : std::false_type {};

template<template<typename,typename>class checker, typename T0, typename T1, typename... Ts>
struct is_any_to_first<checker, T0, T1, Ts...> :
  std::integral_constant< bool, checker<T0, T1>::value || is_any_to_first<checker, T0, Ts...>::value>
{};

Then a 2 line implementation of is_any_same_to_first:

template<typename... Ts>
using is_any_same_to_first = is_any_to_first< std::is_same, Ts... >;

And for completeness, the original is_all, which may also prove useful:

template<template<typename,typename>class checker, typename... Ts>
struct is_all : std::true_type {};

template<template<typename,typename>class checker, typename T0, typename T1, typename... Ts>
struct is_all<checker, T0, T1, Ts...> :
  std::integral_constant< bool, checker<T0, T1>::value && is_all<checker, T0, Ts...>::value>
{};

template<typename... Ts>
using is_all_same = is_all< std::is_same, Ts... >;

Live example of the is_all_same.

Note that calling is_any_same_to_first anything less explicit is asking for trouble. 2/3 people who tried to answer this question, including me, assumed that is_same<A,B,C> is true iff all three are the same type!

How to Define A Variadic Number of Arguments of the , Variadic templates allow any number of template parameters of any type. In this article we see how to do a variadic number of parameters of the SAME type. using conjunction = std::is_same<bool_pack<true,Ts::value. If T and U name the same type (including const/volatile qualifications), provides the member constant value equal to true. Otherwise value is false. Commutativity is satisfied, i.e. for any two types T and U, is_same<T, U>::value == true if and only if is_same<U, T>::value == true. 1 Helper variable template.

Using the relaxed C++14 constexpr functions, these kinds of things are much easier to code, and probably much faster to compile as well, so you could write:

template <class T, class ... Candidates>
constexpr bool is_all_same() {
    bool pairs[] = {std::is_same<T,Candidates>::value...};
    for(bool p: pairs) if(!p) return false;
    return true;
}

template <class T, class ... Candidates>
constexpr bool is_any_same() {
    bool pairs[] = {std::is_same<T,Candidates>::value...};
    for(bool p: pairs) if(p) return true;
    return false;
}

This is enabled by the fact that in C++14 constexpr functions can have for loops.

Variadic function with restricted types, Variadic templates allow any number of template parameters of any type. That functions means to express: “give me all the strings that you want, and using AllStrings = typename conjunction<std::is_same<Ts, std::string>. Yes it is possible. First of all you need to decide if you want to accept only the type, or if you want to accept a implicitly convertible type. I use std::is_convertible in the examples because it better mimics the behavior of non-templated parameters, e.g. a long long parameter will accept an int argument.

[PDF] Fold Expressions in C++17, Unfortunately, the alias templates for the query traits ( is_* ) have not been accepted, so you have to use std::is_same . template <typename . Variadic templates. One of the new features of C++11 is variadic templates.Finally, there's a way to write functions that take an arbitrary number of arguments in a type-safe way and have all the argument handling logic resolved at compile-time, rather than run-time.

std::is_same - is_same, Variadic Template Examples. 2. Do NOT use the varargs mechanism in new C++ code ever. static constexpr bool value = (std::is_same<T1,TN>::value && . If you are C++ programmer, you can use implement similar concept using C++ variadic templates, which is available since C++ 11. If you are new to templates, this might help: C++ Template Functions Explained with an Example Program. Also, this is a good reference: Introduction to C++11 and C++14 with Example Code Snippet.

[PDF] Variadic Templates for C++0x, By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok is_same inherits from integral_constant as being either true_type or  @Quentin: Variadic functions often work (today) with recursion, so you call print with 4 arguments, which calls print with 3 arguments, which calls print with 2 arguments, which calls print with 1 argument => this is the base case (non-variadic function) and the recursion stops.

Comments
  • Since your intent wasn't clear (two people made the same wrong interpretation) I took the liberty to slightly rephrase your question.
  • this is much cleaner than the checked answer, I feel it should get the checkmark instead, even though the question has a c++11 tag
  • The first variation works on C++14, and adding disjunction will make it compile even on C++11.
  • Hmm I see you made the other decision than me (is_all_same instead of is_any). Truth be told, I hesitated to ask OP for clarification about that.
  • Um...This code will only work if all the types are the same. I'm looking for if T is either A, B, or C.
  • isn't is_same_v c++17? Maybe have to use is_same<>::value with c++14
  • @xwl You're right, is_same<>{} works in C++14 too, since struct is_same<> has an operator bool overload.