当前位置:  开发笔记 > 编程语言 > 正文

将流运算符>>评估为布尔值

如何解决《将流运算符>>评估为布尔值》经验,为你挑选了1个好方法。

以下代码在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==中断呢?



1> songyuanyao..:

自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开始,空指针常量定义为:

    一个值为零的整数文字,或者是一个类型的prvalue std::nullptr_t (从C++ 11开始)

    false不是再次; 它不是整数文字.

因此,由于这两个更改,if ((ss >> f) == false)将无法在C++ 11及更高版本中使用.

另一方面,if (!(ss >> f))工作正常,因为有std :: basic_ios :: operator!(对于它来说,在C++ 11之前和之后).

bool operator!() const;

true如果关联的流上发生错误,则返回.具体来说,true如果设置了badbit或failbit ,则返回rdstate().

顺便说一句:由于C++ 11,即使没有std::basic_ios::operator!,explicit operator bool() const也可以if (!(ss >> f))很好地工作,因为在上下文转换的上下文中,explicit考虑了用户定义的转换; 即ss可以在上下文中转换booloperators !.

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有