c++ - 将流运算符 >> 评估为 bool 值

标签 c++ c++11 visual-c++ type-conversion language-lawyer

以下代码在 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 以来有两个行为发生了变化。

  1. 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比较),这是不允许的。

  2. 空指针常量的定义改变了。

    在 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, returns true if badbit or failbit is set in rdstate().

顺便说一句:从 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/

相关文章:

c++ - 让网络摄像头在 OpenCV 中工作

c++ - 我怎么能(暂时)取消类型定义?

c++ - 如何成功清除流?

opencv - 使用openCV快速显示图像

c++ - LD_PRELOAD 导致 linux 命令的段错误

c++ - 编译时常量与运行时常量

c++ - 这是对 unique_ptr 的误用吗?

c++ - 简单参数包扩展 : expected ';'

c++ - 如何使用opencv将图像转换为矩阵?

c++ - 错误LNK2019,如何解决? *更新*