Let's say we have function:
template <typename Kind, typename... Kinds> void foo(){...};
What is the simplest way to check if the type 'Kind' is one of the types 'Kinds' in C++ (including C++1z)?
Variadic templates in C++. 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. Variadic templates can be used for much more than just functions that take an arbitrary number of arguments;
The pack can have arbitarary number of parameters having different types. At the end of compile-time, a variadic template function is translated into multiple solid functions that each of them accepts a certain number of parameters with certain types. There is no explicit for-loop commands to iterate the pack parameters.
If you're concerned with the performance of code that relies on variadic templates, worry not. As there's no actual recursion involved, all we have is a sequence of function calls pre-generated at compile-time. This sequence is, in practice, fairly short (variadic calls with more than 5-6 arguments are rare).
Douglas Gregor and Jaakko Järvi came up with this feature for C++. Variadic arguments are very similar to arrays in C++. We can easily iterate through the arguments, find the size (length) of the template, can access the values by an index, and can slice the templates too.
You could use the following type trait:
template <typename...>
struct is_one_of {
static constexpr bool value = false;
};
template <typename F, typename S, typename... T>
struct is_one_of<F, S, T...> {
static constexpr bool value =
std::is_same<F, S>::value || is_one_of<F, T...>::value;
};
Live Demo
Update C++17
Using the C++17 pattern expansion there is no need for auxiliar class anymore
template <typename Kind, typename... Kinds> void foo(){
/* The following expands to :
* std::is_same_v<Kind, Kind0> || std::is_same_v<Kind, Kind1> || ... */
if constexpr ((std::is_same_v<Kind, Kinds> || ...)) {
// expected type
} else {
// not expected type
}
};
Live Demo
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