Q:

Output a number that may be one of three types

I have a variable x.
It may either be of type char, uint8_t or std::string.
I wish to output the number (not character), using the same expression involving std::cout. This is because I use this expression in generated code.
At code-generation-time, I currently don't know if x will be char, uint8_t or std::string.
std::cout << x << std::endl does not work if x is of type char, since it will output the character and not the number.
std::cout << +x << std::endl does not work if x is of type std::string.
std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? +x : x) << std::endl does not work if x is of type std::string.
std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? static_cast<int>(x) : x) << std::endl does not work if x is of type std::string.
I am aware that std::cout can be configured in various ways by piping std::hex or std::boolalpha, but I know of no possible way to configure std::cout to output a char as a number, without casting the char first.
Is there a way to use reflection, operator overloading, templates or something else 
so that one can have a single unified statement for outputting x, as a number?
For example, if x is 65 with type char, the desired output is 65, not A.

A:

Just format a helper and specialize the versions you want to customize appropriately. For example:
#include <iostream>

template <typename T>
struct formatter {
    T const& value;
};

template <typename T>
formatter<T> format(T const& value) {
    return formatter<T>{value};
}

template <typename T>
std::ostream& operator<< (std::ostream& out, formatter<T> const& v) {
    return out << v.value;
}

std::ostream& operator<< (std::ostream& out, formatter<char> const& v) {
    return out << int(v.value);
}

template <std::size_t N>
std::ostream& operator<< (std::ostream& out, formatter<char[N]> const& v) {
    return out << '\'' << v.value << '\'';
}

int main() {
    std::cout << "char=" << format('c') << " "
              << "int=" << format(17) << " "
              << "string=" << format("foo") << " "
              << "\n";
}

