Reputation: 777
This is an open discussion about different ways to enable function overloading for parameters of only char
, signed char
or unsigned char
type with the help of type traits in terms of C++11 template compiling.
Though satisfactory, a compound logic of std::enable_if
and std::is_same
type assertion (see PS) is not smart in that all matching types, particularly char
in spite of signedness, are used in enumeration. Therefore I'm hoping someone can specify some other clause or compound logic that might facilitate type assertions better (maybe std::is_integral
, std::is_arithmetic
or std::is_signed
?).
PS:
template <typename type>
void foo(std::enable_if<std::is_same<type, char>::value||std::is_same<type, signed char>::value||std::is_same<type, unsigned char>::value, type> x)
{
}
Upvotes: 2
Views: 1216
Reputation: 21900
Well Jesse already provided a solution, but I'll leave mine here anyway.
// Tests whether the first template argument is equal to at least
// one of the rest of them
// e.g. any_is_same<int, char, bool, int>::value == true
// e.g. any_is_same<int, char, bool, std::string>::value == false
template<typename...>
struct any_is_same;
// Base cases
template<typename T, typename... Types>
struct any_is_same<T, T, Types...> {
enum { value = true };
};
template<typename T>
struct any_is_same<T> {
enum { value = false };
};
// Recursive
template<typename T, typename Head, typename... Tail>
struct any_is_same<T, Head, Tail...> {
enum { value = any_is_same<T, Tail...>::value };
};
// Helper
template<typename T>
struct is_some_char {
enum { value = any_is_same<T, char, signed char, unsigned char>::value };
};
template <typename type, typename std::enable_if<is_some_char<type>::value, int>::type = 0>
void foo(type x)
{
}
You can reuse the any_is_same
type trait if you pretend to do the same for other types(like int
/unsigned int
/signed int
/...):
template<typename T>
struct is_some_int {
enum { value = any_is_same<T, int, signed int, unsigned int>::value };
};
Demo here.
Upvotes: 1
Reputation: 52365
If you want a type trait like that, you will have to make one yourself:
template <typename T>
struct is_char
{
static const bool value = std::is_same<T, char>::value ||
std::is_same<T, signed char>::value ||
std::is_same<T, unsigned char>::value;
};
template <typename T>
void f(T t, typename std::enable_if<is_char<T>::value>::type* = 0)
{
}
Upvotes: 3