2014-02-20 45 views
2

使用流操作符的C++代碼失敗。我無法弄清楚,爲什麼第二次打印「DEF」不工作::爲什麼第二條語句是打印十六進制值

#include <iostream> 
#include <sstream> 
struct logger :public std::ostringstream {}; 

struct logger_flush {}; 

logger_flush endl; 

std::ostream& operator << (std::ostream& os, const logger_flush& lf) { 
    logger& oss = dynamic_cast<logger&>(os); 
    std::cout << oss.str() << std::endl; 
} 

int main() 
{ 
    logger() << 100 << "ABC?" << endl; 
    logger() << "DEF" << endl; 
} 

輸出是:

100ABC?

0x40168d

+0

似乎與gcc一起工作。 http://ideone.com/XylUCx – mkaes

+1

甚至不爲我編譯。您在運營商<<功能中沒有返回任何內容。 – user1052842

+1

@ user1052842 - 我認爲這應該是一個警告。 –

回答

3

logger()是一個右值,這就是爲什麼叫::operator<<(logger(), "DEF")你想不起作用:的operator<<是重載接受左值的參考參數,右值不能綁定到非const左值引用。

但是,右值類允許調用方法,因此過載logger().operator<<((void*)"DEF")可用,並且它成爲logger() << "DEF"的最佳匹配。

它適用於logger() << 100 << "ABC?" << endl;,因爲logger() << 100返回一個左值引用,並且該左值引用是::operator<<的有效參數。

3

這應該在C++ 11中工作,因爲ostream& operator<<(ostream&& os, const T& value)重載,它允許您使用流作爲右值。

在C++中03,因爲void*過載是一個構件(它可以在右值被稱爲),而char const*超載是非構件將打印的地址,和第一個參數是一個ostream&,它不能綁定到rvalues。

+0

在我的電腦上無法使用3.3版本。在重載的'operator <<'中缺少返回語句是未定義的行爲,並且這個UB最終導致信號EXC_BAD_INSTRUCTION被引發。幸運的是,對這個UB的響應沒有調用'erase_hard_drive()'函數。 –

+0

@DavidHammen禁止未定義的行爲,它將工作。我的答案主要是關於爲什麼'void *'重載選擇在'char const *'之上。 – Simple

+0

修復了UB問題之後,我使用了clang ++(clang版本3.3),爲-std = C++ 03和-std = C++ 11獲得了相同的輸出。 –

相關問題