gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 16:37:55 28 4
gpt4 key购买 nike

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

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

A question on comp.lang.c++.moderated也没有带来任何答案。

最佳答案

使用旧的(阅读: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 页:

The istream and ostream types rely on a conversion function to enable statements such as

while (cin >> x) cout << x;

The input operation cin>>x returns an istream&. That value is implicitly converted to a value indicating the state of cin. The value can then be tested by while. However, it is typically not a good idea to define an implicit conversion from one type to another in such a way that information is lost in the conversion.

在 C++ 中有很多似乎是可爱或聪明胜过一致的胜利。如果 C++ 足够聪明,可以将上述循环处理为:

while (!(cin >> x).fail()) cout << x;

因为这虽然更冗长且标点符号更多,但对于初学者来说更清晰。

...实际上,仔细想想,我不喜欢这两种结构。拼写出来:

for(;;)
{ cin >> x;
if(!cin)
break;
cout << x;
}

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

但我离题了。

关于c++ - 为什么 std::basic_ios 会重载一元逻辑否定运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3222131/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com