[英]Evaluating stream operator >> as boolean
The following code compiles in Visual Studio 2008 but fails in Visual Studio 2013 and later. 以下代码在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";
The error message is 错误消息是
error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_istream>' (or there is no acceptable conversion)
错误C2678:二进制'==':找不到哪个运算符带有'std :: basic_istream>'类型的左操作数(或者没有可接受的转换)
and is successfully fixed by changing as follows: 并通过以下更改成功修复:
if (!(ss >> f))
std::cout << "Parse error\n";
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? 我的问题是,涉及哪些运算符或强制转换或
ios
标志允许流读取首先被评估为布尔值,然后为什么缺少operator==
打破它?
Two behaviors changed since C++11. 自C ++ 11以来,两种行为发生了变化
The behavior of std::basic_ios::operator bool changed. std :: basic_ios :: operator bool的行为发生了变化。
operator void*() const; (1) (until C++11) explicit operator bool() const; (2) (since C++11)
Note since C++11 operator bool()
is declared as explicit
; 注意,因为C ++ 11
operator bool()
被声明为explicit
; but for if ((ss >> f) == false)
, ss
(ie the return value of (ss >> f)
) needs to be implicit converted to bool
(to be compared with false
), which is not allowed. 但对于
if ((ss >> f) == false)
, ss
(即(ss >> f)
的返回值)需要隐式转换为bool
(与false
进行比较),这是不允许的。
The definition of the null pointer constant changed. 空指针常量的定义已更改。
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之前,可以使用
operator void*()
并且它不是explicit
(在C ++ 11之前没有这种显式的用户定义转换 ),在C ++ 11之前,空指针常量定义为:
an integral constant expression rvalue of integer type that evaluates to zero (until C++11)
整数类型的整数常量表达式rvalue,其计算结果为零(直到C ++ 11)
which means false
could be used as a null pointer constant. 这意味着
false
可以用作空指针常量。 So ss
could be implicitly converted to void*
and then compared with false
(as the null pointer). 所以
ss
可以隐式转换为void*
,然后与false
比较(作为空指针)。
From C++11, the null pointer constant is defined as: 从C ++ 11开始,空指针常量定义为:
an integer literal with value zero, or a prvalue of type
std::nullptr_t
(since C++11)一个值为零的整数文字,或者类型为
std::nullptr_t
的prvalue(自C ++ 11起)
while false
is not again; 而
false
不再是; it's not an integer literal . 它不是整数文字 。
So, because of these two changes, if ((ss >> f) == false)
won't work in C++11 and later. 因此,由于这两个变化,
if ((ss >> f) == false)
在C ++ 11及更高版本中不起作用。
On the other hand, if (!(ss >> f))
works fine because there's std::basic_ios::operator! 另一方面,
if (!(ss >> f))
工作正常,因为有std :: basic_ios :: operator! (both before and after C++11) for it. (对于它来说,在C ++ 11之前和之后)。
bool operator!() const;
Returns
true
if an error has occurred on the associated stream.如果关联的流上发生错误,则返回
true
。 Specifically, returnstrue
if badbit or failbit is set inrdstate()
.具体来说,如果在
rdstate()
设置了rdstate()
或failbit,则返回true
。
BTW: Since C++11, even without std::basic_ios::operator!
BTW:从C ++ 11开始,即使没有
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; ,
explicit operator bool() const
也可以使if (!(ss >> f))
运行良好,因为在上下文转换的上下文中,考虑了explicit
用户定义转换; ie ss
could be contextually converted to bool
for operators !
即
ss
可以在上下文中转换为bool
给operators !
. 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.