#include <iostream>

namespace foo_detail {
template <typename T>
struct remap {
    // Default: Output type is the same as input type.
    typedef T type;
};

template <>
struct remap<char> {
    typedef unsigned char type;
};

template <>
struct remap<signed char> {
    typedef unsigned char type;
};

template <typename T>
void foo(int x);

template <>
void foo<unsigned char>(int x) {
    std::cout << "foo<unsigned char>(" << x << ") called\n";
}
}

template <typename T>
void foo(int x) {
    foo_detail::foo<typename foo_detail::remap<T>::type>(x);
}

int main() {
    foo<char>(13);
    foo<signed char>(13);
    foo<unsigned char>(13);
}