为什么std :: basic_ios会重载一元逻辑否定运算符?

sbi*_*sbi 9 c++

C++ IO流的基类std::basic_ios定义operator void*()为返回!fail()operator!()返回fail().这让我想知道为什么我们需要它operator!().当然,!is也可以通过隐式调用operator void*()和否定其结果来工作.

我在这里遗漏了什么,还是纯粹出于历史原因而std::basic_ios::operator!()定义的?

一个在comp.lang.c ++的问题.主持并没有带来任何答案要么.

Mik*_*one 6

使用旧的(读取:不久之后cfront)C++编译器,编译器无法保证在需要时隐式调用对象上的类型转换操作符.如果iostream没有operator !声明,那么你不可能期望!cout在所有情况下工作.C++ 89(或者调用前C++ 98标准的任何内容)只是将该区域定义为未定义.

这也是为什么operator void*()超载,而不是operator intoperator bool.(bool当时在标准中甚至没有作为自己的类型存在.)我记得我的教授告诉我if(),在引擎盖下,期望void*在C++中,因为该类型可以作为相对于那些表达式的"超集"类型将传递给if语句的结果类型,但我没有在任何地方找到这个拼写.

这是在gcc 2的时候,当大多数人不支持模板或异常时,或者如果他们这样做,并没有完全支持它们,所以使用模板进行元编程C++仍然是一个理论练习,你确保检查那个operator new没有不返回空指针.

这让我疯了几年.

Stroustrup的The C++ Programming Language,第3版的有趣摘录.(1997),第276页:

istream对象ostream的类型依靠转换功能,使语句,如

while (cin >> x) cout << x;
Run Code Online (Sandbox Code Playgroud)

输入操作cin >> x返回一个istream&.该值被隐式转换为表示cin状态的值.然后可以通过while测试该值.但是,定义从一种类型到另一种类型的隐式转换通常不是一个好主意,因为信息在转换中会丢失.

C++中有很多东西似乎是可爱或聪明的胜利.如果C++足够聪明以处理上述循环,我不介意一点:

while (!(cin >> x).fail()) cout << x;
Run Code Online (Sandbox Code Playgroud)

因为这对于一个初级程序员来说更加冗长和标点符号更清晰.

......实际上,想一想,我不喜欢这些结构中的任何一个.拼写出来:

for(;;)
{   cin >> x;
    if(!cin)
        break;
    cout << x;
}
Run Code Online (Sandbox Code Playgroud)

为什么我更喜欢这个?因为这个版本使得如何将代码扩展到例如一次处理两个读取而不是一个读取更加清晰.例如,"现有代码复制一系列浮点值.我们希望您更改它,以便将浮点值配对并将它们写出来,每行两个,因为我们现在使用的是复数."

但我离题了.