繁体   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