次の関数を検討してください。
void f(const char* str);
stringstream を使用して文字列を生成し、それをこの関数に渡したいとします。1 つのステートメントでそれを実行したい場合は、次のようにします。
f((std::ostringstream() << "Value: " << 5).str().c_str()); // error
これによりエラーが発生します: 'str()' は 'basic_ostream' のメンバーではありません。では、operator<< は ostringstream ではなく ostream を返します。ostringstream にキャストして戻すのはどうですか?
1) このキャストは安全ですか?
f(static_cast<std::ostringstream&>(std::ostringstream() << "Value: " << 5).str().c_str()); // incorrect output
これで、operator<<("Value: ") 呼び出しが判明しました。実際には、ostream の operator<<(void*) を呼び出して、16 進アドレスを出力しています。これは間違っています。テキストが必要です。
2) 一時的な std::ostringstream() の operator<< が ostream 演算子を呼び出すのはなぜですか? 確かに、一時には「ostream」ではなく「ostringstream」のタイプがありますか?
一時的にキャストして、正しいオペレーター呼び出しを強制することもできます!
f(static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << "Value: " << 5).str().c_str());
これは機能しているようで、「Value: 5」を f() に渡します。
3) 現在、未定義の動作に依存していますか? キャストは珍しいようです。
最良の代替手段は次のようなものであることは承知しています。
std::ostringstream ss;
ss << "Value: " << 5;
f(ss.str().c_str());
...しかし、私はそれを1行で行う動作に興味があります。誰かが (疑わしい) マクロを作りたいとします:
#define make_temporary_cstr(x) (static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << x).str().c_str())
// ...
f(make_temporary_cstr("Value: " << 5));
これは期待どおりに機能しますか?