文字型三種
「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; }
みたいなパターンですね。