[英]Evaluating stream operator >> as boolean
以下代碼在Visual Studio 2008中編譯,但在Visual Studio 2013及更高版本中失敗。
std::string str("foo");
std::stringstream ss(str);
float f = 0;
if ((ss >> f) == false)
std::cout << "Parse error\n";
錯誤消息是
錯誤C2678:二進制'==':找不到哪個運算符帶有'std :: basic_istream>'類型的左操作數(或者沒有可接受的轉換)
並通過以下更改成功修復:
if (!(ss >> f))
std::cout << "Parse error\n";
我不太了解這一點。 我的問題是,涉及哪些運算符或強制轉換或ios
標志允許流讀取首先被評估為布爾值,然后為什么缺少operator==
打破它?
自C ++ 11以來,兩種行為發生了變化
std :: basic_ios :: operator bool的行為發生了變化。
operator void*() const; (1) (until C++11) explicit operator bool() const; (2) (since C++11)
注意,因為C ++ 11 operator bool()
被聲明為explicit
; 但對於if ((ss >> f) == false)
, ss
(即(ss >> f)
的返回值)需要隱式轉換為bool
(與false
進行比較),這是不允許的。
空指針常量的定義已更改。
在C ++ 11之前,可以使用operator void*()
並且它不是explicit
(在C ++ 11之前沒有這種顯式的用戶定義轉換 ),在C ++ 11之前,空指針常量定義為:
整數類型的整數常量表達式rvalue,其計算結果為零(直到C ++ 11)
這意味着false
可以用作空指針常量。 所以ss
可以隱式轉換為void*
,然后與false
比較(作為空指針)。
從C ++ 11開始,空指針常量定義為:
一個值為零的整數文字,或者類型為
std::nullptr_t
的prvalue(自C ++ 11起)
而false
不再是; 它不是整數文字 。
因此,由於這兩個變化, if ((ss >> f) == false)
在C ++ 11及更高版本中不起作用。
另一方面, if (!(ss >> f))
工作正常,因為有std :: basic_ios :: operator! (對於它來說,在C ++ 11之前和之后)。
bool operator!() const;
如果關聯的流上發生錯誤,則返回
true
。 具體來說,如果在rdstate()
設置了rdstate()
或failbit,則返回true
。
BTW:從C ++ 11開始,即使沒有std::basic_ios::operator!
, explicit operator bool() const
也可以使if (!(ss >> f))
運行良好,因為在上下文轉換的上下文中,考慮了explicit
用戶定義轉換; 即ss
可以在上下文中轉換為bool
給operators !
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.