评估流运算符>>作为布尔值 [英] Evaluating stream operator >> as boolean

查看:74
本文介绍了评估流运算符>>作为布尔值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在Visual Studio 2008中编译,但在Visual Studio 2013及更高版本中失败.

The following code compiles in Visual Studio 2008 but fails in Visual Studio 2013 and later.

std::string str("foo");
std::stringstream ss(str);
float f = 0;

if ((ss >> f) == false)
    std::cout << "Parse error\n";

错误消息是

错误C2678:二进制'==':未找到需要左手操作的运算符 类型'std :: basic_istream>'的操作数(或 没有可接受的转换)

error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_istream>' (or there is no acceptable conversion)

,并通过以下更改成功修复:

and is successfully fixed by changing as follows:

if (!(ss >> f))
    std::cout << "Parse error\n";

我对此不太了解.我的问题是,涉及什么运算符或强制转换或ios标志,这些标志首先允许将读取的流评估为布尔值,然后为什么没有operator==会破坏它呢?

I'm not understanding this well. My question is, what operator or cast or maybe ios flags are involved that allow the stream read to be evaluated as a boolean in the first place, and then why does the lack of an operator== break it?

推荐答案

自C ++ 11以来发生了两种变化.

Two behaviors changed since C++11.

  1. std :: basic_ios ::的行为运算符bool 已更改.

  1. The behavior of std::basic_ios::operator bool changed.

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比较).

Note since C++11 operator bool() is declared as explicit; but for if ((ss >> f) == false), ss (i.e. the return value of (ss >> f)) needs to be implicit converted to bool (to be compared with false), which is not allowed.

空指针常量的定义已更改.

在使用C ++ 11 operator void*()之前,不能使用explicit(在C ++ 11之前,没有这样的空指针常量定义为:

Before C++11 operator void*() could be used and it's not explicit (before C++11 there's no such explicit user-defined conversion), and before C++11 the null pointer constant is defined as:

整数类型的整数常量表达式右值,其值为零 (直到C ++ 11)

an integral constant expression rvalue of integer type that evaluates to zero (until C++11)

表示false可用作空指针常量.因此,可以将ss隐式转换为void*,然后与false(作为空指针)进行比较.

which means false could be used as a null pointer constant. So ss could be implicitly converted to void* and then compared with false (as the null pointer).

从C ++ 11开始,空指针常量定义为:

From C++11, the null pointer constant is defined as:

整数文字,其值为零,或类型为std::nullptr_t的prvalue (自C ++ 11起)

an integer literal with value zero, or a prvalue of type std::nullptr_t (since C++11)

false不再出现;它不是整数文字.

因此,由于这两个更改,if ((ss >> f) == false)在C ++ 11和更高版本中将不起作用.

So, because of these two changes, if ((ss >> f) == false) won't work in C++11 and later.

另一方面,if (!(ss >> f))可以正常工作,因为其中有 std :: basic_ios :: operator!(在C ++ 11之前和之后).

On the other hand, if (!(ss >> f)) works fine because there's std::basic_ios::operator! (both before and after C++11) for it.

bool operator!() const;

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

Returns true if an error has occurred on the associated stream. Specifically, returns true if badbit or failbit is set in rdstate().

BTW:由于C ++ 11,即使没有std::basic_ios::operator!explicit operator bool() const也可以使if (!(ss >> f))正常工作,因为在

BTW: Since C++11, even without std::basic_ios::operator!, explicit operator bool() const could also make if (!(ss >> f)) works well, because in the context of contextual conversion, explicit user-defined conversion is considered; i.e. ss could be contextually converted to bool for operators !.

这篇关于评估流运算符&gt;&gt;作为布尔值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆