文字型三種

「charでなく、signed char/unsigned charをストリームに出力した場合何がでるんだっけ?」
Boost.懇親会でCryoliteさんと話していて、宿題にしていた疑問です。
何か罠があっていつもキャストしてから出力していたのですが、思い出せず。
帰ってすぐ確認しました。

#include <iostream>

int main()
{
    std::cout << 'c' << std::endl;
    std::cout << static_cast<signed char>('s') << std::endl;
    std::cout << static_cast<unsigned char>('u') << std::endl;
    std::cout << L'w' << std::endl;

    std::cout << "char" << std::endl;
    std::cout << reinterpret_cast<const signed char*>("signed char") << std::endl;
    std::cout << reinterpret_cast<const unsigned char*>("unsigned char") << std::endl;
    std::cout << L"wchar_t" << std::endl;

    std::wcout << 'c' << std::endl;
    std::wcout << static_cast<signed char>('s') << std::endl;
    std::wcout << static_cast<unsigned char>('u') << std::endl;
    std::wcout << L'w' << std::endl;

    std::wcout << "char" << std::endl;
    std::wcout << reinterpret_cast<const signed char*>("signed char") << std::endl;
    std::wcout << reinterpret_cast<const unsigned char*>("unsigned char") << std::endl;
    std::wcout << L"wchar_t" << std::endl;
}

実行結果

c
s
u
119
char
signed char
unsigned char
00000001400053B8
c
115
117
w
char
00000001400053D0
00000001400053E0
wchar_t

なんかExceptional C++辺りで似た問題を見た気もしますが、signed/unsignedが付いても結果が変わりませんでした。
8桁の十六進になっている箇所はvoid*として出力された箇所です。(VC++9.0/x64)
3桁の十進はintとして出力された箇所です。

オーバーロードも三種だと思っていたのにもっとありました。

// c
template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& out, charT c);

// widen(c)
template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& out, char c);

// c
template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, char c);

// (char)c
template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, signed char c);

// (char)c
template<class traits>
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, unsigned char c);

ポインタ版も同じだけあります。
この結果から考えると、自分がキャストしていたのは、

void print_ui8(boost::uint8_t n)
{
    // 文字列でなく、8ビットの数値として出力したい
    std::cout << static_cast<unsigned>(n) << std::endl;
}

みたいなパターンですね。