[英]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以来,两种行为发生了变化
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开始,空指针常量定义为:
一个值为零的整数文字,或者类型为
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
可以在上下文中转换为bool
给operators !
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.