メンバー関数を持たないoperator<<
for ストリームが返されます。キャストを使用する必要があります。std::ostream &
str()
static_cast<std::ostringstream&>(std::ostringstream() << etc).str()
一時ストリームを使用する場合の C++03 と C++11 の違い!
C++03
ただし、(C++03 では) は一時オブジェクトをstd::ostringstream()
作成することに注意してください。これは、一時オブジェクトにバインドできない最初の引数を受け入れるため、非メンバーオーバーロードをoperator<<
最初に呼び出すことができないことを意味します。一時オブジェクトは、メンバー関数のみを呼び出すことができます。<<
std::ostream&
つまり、次のように指定すると、 stringではなくaddressが返されます。
static_cast<std::ostringstream&>(std::ostringstream() << "XYZ").str()
char const*
引数として受け取るオーバーロードは、呼び出すことができない非メンバー関数void const*
であるため、上記のコードは、引数として受け取るメンバー関数を呼び出すことになり、文字列リテラルのアドレスを出力する に"XYZ"
暗黙的に変換されます。void const*
一時関数がメンバー関数を呼び出すと、残りのチェーン<<
は非メンバーオーバーロードを呼び出す可能性がありますstd::ostream&
。これは、メンバー関数が の非メンバーオーバーロードの最初の引数にバインドできるようになるためです。したがって、次のコードは( の代わりに)アドレスとそれに続く string を出力します。operator<<
"XYZ"
"ABC"
static_cast<std::ostringstream&>(std::ostringstream() << "XYZ" << "ABC").str()
オンラインデモ:
C++11
C++11 では、この問題は非メンバー関数 (27.7.3.9) を追加することで修正されました。この関数は、最初の引数を右辺値参照として受け取り、呼び出しを適切な関数 (メンバーまたは非メンバー) に転送します。したがって、次のように出力XYZ
されABC
ます。