Yang
Yang

Reputation: 777

Function overloading for char, signed char or unsigned char parameter type in terms of compiling template

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

Answers (2)

mfontanini
mfontanini

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

Jesse Good
Jesse Good

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

Related Questions