【发布时间】:2015-06-27 20:25:45
【问题描述】:
我正在阅读this。 @NPE 给出的答案谈到了有趣的历史事实并说,
- 在早期的 C++ 中曾经有一个特殊的关键字(重载) 用于将标识符声明为重载;
那么,删除 overload 关键字的原因是什么?我没有 Stroustrup 的Design and Evolution of C++。重载关键字有什么问题?
【问题讨论】:
标签: c++ overloading
我正在阅读this。 @NPE 给出的答案谈到了有趣的历史事实并说,
那么,删除 overload 关键字的原因是什么?我没有 Stroustrup 的Design and Evolution of C++。重载关键字有什么问题?
【问题讨论】:
标签: c++ overloading
Stroustrup 在 D&E 11.2.4 “overload 关键字”中提到,overload 关键字在“合并”(或使用)两个使用相同函数名称(没有命名空间*)的库时会引起麻烦。例如,C 标头 math.h 中的 sqrt 与 C++ 标头 complex 中的 sqrt(complex)。如果其中一个将函数声明为可重载,但另一个没有,则您必须按照重载发生之前启用重载的顺序包含标头:
// #include <complex>
overload sqrt;
complex sqrt(complex);
// #include <math.h>
double sqrt(double); // fine
// ---------------------------
// #include <math.h>
double sqrt(double);
// #include <complex>
overload sqrt; // ERROR: cannot allow overloading
// of an already declared function
complex sqrt(complex);
可能的解决方法是“除了最简单的情况外,在所有情况下都无法管理”。
(*) overload 关键字在 1989 年发布的 CFront 2.0 中已过时。命名空间于 1993 年被引入标准化提案。
关键字的初衷是为了应对两个恐惧:
- 担心可能会出现未检测到的歧义。
- 担心程序无法正确链接,除非程序员明确声明哪些函数应该是 超载。
事实证明,前一种恐惧在很大程度上是毫无根据的。实际使用中发现的少数问题,通过与顺序无关的重载解析规则来处理。事实证明,后一种恐惧在与重载无关的 C 单独编译规则的一般问题中是没有根据的。
【讨论】:
#ifdef __cplusplus /*newline*/ overload sqrt; /*newline*/ #endif 之类的内容可能被认为是那些“无法管理”的解决方法之一,或者如果外部库标头可能不会更改则不可能
math.h,例如因为它是一个系统头文件并且代码必须在许多不同的平台上编译,所以(字面上)不可能添加overload sqrt;。
<math.h> 必须是系统标头。这通常是一个非常糟糕的主意。头文件应该是编译器实现的一部分。当然,如果操作系统提供了一个预制的sqrt,你会想用它作为实现者。这并不意味着您应该盲目地公开每个功能。