以下代码在 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";
错误信息是
error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_istream>' (or there is no acceptable conversion)
并通过如下更改成功修复:
if (!(ss >> f))
std::cout << "Parse error\n";
我不是很了解这个。我的问题是,涉及什么运算符或转换或可能 ios
标志允许首先将流读取评估为 bool 值,然后为什么缺少 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 之前没有这样的 explicit user-defined conversion ),并且在之前C++11 the null pointer constant定义为:an integral constant expression rvalue of integer type that evaluates to zero (until C++11)
这意味着
false
可以用作空指针常量。因此,ss
可以隐式转换为void*
,然后与false
(作为空指针)进行比较。从C++11开始,空指针常量定义为:
an integer literal with value zero, or a prvalue of type
std::nullptr_t
(since C++11)while
false
不再是;这不是 integer literal .
因此,由于这两个更改,if ((ss >> f) == false)
将无法在 C++11 及更高版本中工作。
另一方面,if (!(ss >> f))
工作正常,因为有 std::basic_ios::operator! (在 C++11 之前和之后)。
bool operator!() const;
Returns
true
if an error has occurred on the associated stream. Specifically, returnstrue
if badbit or failbit is set inrdstate()
.
顺便说一句:从 C++11 开始,即使没有 std::basic_ios::operator!
,explicit operator bool() const
也可以使 if ( !(ss >> f))
效果很好,因为在 contextual conversion 的上下文中, explicit
考虑用户定义的转换;即 ss
可以根据上下文转换为 bool
for operators !
。
关于c++ - 将流运算符 >> 评估为 bool 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41564040/