簡體   English   中英

將流運算符>>評估為布爾值

[英]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以來,兩種行為發生了變化

  1. 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進行比較),這是不允許的。

  2. 空指針常量的定義已更改。

    在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可以在上下文中轉換為booloperators !

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM