この質問のように、SBRM/RAII を使用してクラス経由でストリーミングすることを実験しているので、
SBRM(x) << "test";
デストラクタでいくつかの追加機能を実行できますが、私のテンプレートの知識は限られているようです。
私が持っているもの(わかりやすくするために単純化)は次のとおりです。
#include <iostream>
#include <sstream>
class SBRM
{
public:
SBRM(int j) : i(j) {}
~SBRM() { std::cout << "SBRM(" << i << "): " << oss.str() << std::endl; }
template<typename T> SBRM& operator<<(T& in) { oss << in; return *this; }
// SBRM& operator<<(const long long& in) { oss << std::hex << "0x" << in; return *this; }
SBRM& operator<<(const double& in) { oss << in; return *this; }
SBRM& operator<<(const void* in) { oss << in; return *this; }
private:
int i;
std::ostringstream oss;
};
int main()
{
std::string ttt = "world";
const int i = 3;
SBRM(1) << "Hello";
SBRM(2) << ttt;
SBRM(3) << 0x1234567890123ll;
SBRM(4) << &i;
SBRM(5) << 5;
SBRM(6) << 0.23;
SBRM(7) << i;
SBRM(8) << 5 << ", " << ttt << ", " << &i;
}
この種の作品:
SBRM(1): Hello
SBRM(2): world
SBRM(3): 3.20256e+14
SBRM(4): 0xbf8ee444
SBRM(5): 5
SBRM(6): 0.23
SBRM(7): 3
SBRM(8): 5, world, 0xbf8ee444
しかし、私の主な懸念は、(文字列以外の) リテラルを使用するときにコンパイラがテンプレートをオーバーロードする必要があるのはなぜですか?
これを回避するためのトリックはありますか、それとも間違ったアプローチを取っていますか? 私は今マクロを使用することに頼っているので、他の提案は大歓迎です
NOT_QUITE_SBRM_MACRO(3, "At least, " << 5 << ", this works");
この問題は gcc 4.1.2 で見られます。および 4.4.3。オーバーロードされた関数がなければ、次のようになります。
sbrm-stream.cpp: In function ‘int main()’:
sbrm-stream.cpp:27: error: no match for ‘operator<<’ in ‘SBRM(3) << 320255973458211ll’
sbrm-stream.cpp:10: note: candidates are: SBRM& SBRM::operator<<(T&) [with T = long long int]
sbrm-stream.cpp:28: error: no match for ‘operator<<’ in ‘SBRM(4) << & i’
sbrm-stream.cpp:10: note: candidates are: SBRM& SBRM::operator<<(T&) [with T = const int*]
...