デバッグ時によく使う、変数名とその中身を同時に表示するPRINTの紹介です。
これは#defineを使うことで実現できます。
#include <string>
#include <iostream>
#define PRINT(A) std::cout << (#A) << ":" << (A) << std::endl;
int main(){
int n = 42;
std::string str = "test";
char c = n;
PRINT(n);
PRINT(str);
PRINT(c);
}
出力結果
n:42
str:test
c:*
charは文字として表示されていますね。
これのほうが便利な場合もありますが、1バイトの変数として使っていると不便です。
特に、0とか1とか入っていると見えない文字になりますし。
そこで、charだったときだけintにするようにします。
template<typename T>
const T &stream_cast(const T&n){return n;}
int stream_cast(char n){return n;}
#define PRINT(A) std::cout << (#A) << ":" << stream_cast(A) << std::endl;
出力結果
n:42
str:test
c:42
うまくいったのですが、これをヘッダに書いて複数のファイルでincludeすると
stream_castがすでに定義されているというエラーが出ます。
stream_cast(char)の方もテンプレートで定義できればいいんですが…。
ということで苦肉の策がこれ。
template<typename T>
struct stream_cast{
const T&operator() (const T& n){ return n; }
};
template<>
struct stream_cast<char>{
int operator() (char n){ return n; }
};
#define PRINT(A) std::cout << (#A) << ":" << stream_cast<decltype(A)>()(A) << std::endl;
decltypeが入ってC++11になってしまった…。
C++03でも書ける方法をだれかボスケテ。