2011-06-18 24 views
2

期待される文字列を"Bar"として出力するのではなく、次のコードはポインタと思われるものを出力します。Stringstream出力ポインタの出力

#include <sstream> 
#include <iostream> 

int main() 
{ 
    std::stringstream Foo("Bar"); 
    std::cout << Foo << std::endl; // Outputs "0x22fe80." 
    return 0; 
} 

これはFoo.str()を使用することによって回避することができますが、それは過去の私のためにいくつかの問題を引き起こしています。この奇妙な行動の原因は何ですか?それはどこに文書化されていますか?

+1

これは既に回答があったので、あなたが好奇心が強い場合に備えて、アドレスの意味をここに入れてもよいでしょう。通常、ストリームをブール値のコンテキストでテストできるようにするには、演算子void *がオーバーロードされますが、これは 'operator void *()const {return(fail()?0:(void *)this)のようなコードになります。 } '(失敗フラグがセットされていない場合)は、オブジェクト自体のアドレスを返します。いくつかの実装では、これは、クラスのメンバーか仮想テーブルポインタのいずれかのアドレスを意味します。少なくともvC++では後者を行うようです。 – lccarrasco

答えて

6

これは、Foo.str()を使用することで回避できますが、過去に私に問題が発生しています。この奇妙な行動の原因は何ですか?それはどこに文書化されていますか?

これはまったく変わっていません。

ストリームはストリームであり、ストリングではありません。

メンバ関数.str()で[文字列]バッファを取得できます。これは回避策ではありません。APIです。それはあなたのC++標準ライブラリのリファレンスで文書化されていなければなりません。そうでなければ、あなたの参照は不完全/間違っています。

(少し奇妙である何あなたがコンパイルエラーではなく、メモリアドレスを取得することであり、それがされ、プリC++ 0xの標準ライブラリの安全ブールイディオムを使用しているため、カバーとして別の答えで)

+0

さて、それは本当に安全なブール*イディオムです。それの不自由な形のようにもっと... – Xeo

+0

@ええと:まあ、何でも。それは少なくとも曖昧に関連している。 :)私の答えの一部を非規範的だと考えてください! –

+0

@ Xeo:C++の 'operator bool'よりも安全です03: – Vitus

2

std::stringstreamはストリームに挿入されていないものとします。そのため、あなたはstr()メソッドを持っています。

あなたが観察している行動はstd::stringstreamは、ストリームをテストするために使用されているものであるvoid*への変換、持っているという事実によるものである:C++ 11では

if(Foo) { // this uses the conversion to void* 
} 

を、この変換を交換しますコンパイルしないように、このコードを引き起こす、BOOLする明示的な変換によって:

std::cout << Foo << std::endl; 
+0

なぜそれはコンパイルされませんか? '1'や何かを出力しないのでしょうか? – Maxpm

+2

いいえ、変換が明示的であるため、 'std :: cout << bool(Foo);'と書く必要があります。詳細については、この他の答えを確認してください:http://stackoverflow.com/questions/6242296/conversion-function-for-error-checking-considered-good/6242355#6242355 –

0

(1)のstd :: COUT < <フー< <のstd :: ENDLを使用します。 stringstreamが既に "< <"にオーバーロードしていることを確認する必要があります。

(2)STDを使用し、 "< <" をオーバーロードがない場合:: COUT < <フー< <はstd :: ENDL。 Fooのアドレスを出力することがあります。