2011-06-18 224 views
2

而不是輸出期望的字符串"Bar",下面的代碼輸出看起來是指針的東西。打印字符串流輸出指針

#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()獲取[string]緩衝區。這不是一個解決方法:它是API。它應該記錄在你的C++標準庫引用中,如果不是,那麼你的引用是不完整/錯誤的。

(什麼稍微奇怪的是,你得到一個內存地址,而不是編譯錯誤,也就是說,由於在預的C++ 0x標準庫使用安全布爾成語的,如覆蓋在另一個答案。)

+0

嗯,它是真正的*安全布爾*成語。更像是一些殘廢的形式... – Xeo

+0

@Xeo:恩,不管。至少隱約相關。 :)考慮一下我的答案是非規範性的! –

+0

@Xeo:它比C++ 03中的'operator bool'更安全:) – Vitus

2

A std::stringstream不應插入到流中。這就是爲什麼你有str()方法。

你觀察的行爲是由於這樣的事實,std::stringstream具有轉換到void*,這是用來測試流:

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

在C++ 11,這個轉換被替換通過顯式轉換爲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 ::法院< <富< <的std :: ENDL;你應該確保stringstream已經超載「< <」。

(2)如果沒有過載 「< <」,使用std ::法院< <富< <的std :: ENDL;可輸出Foo的地址。