为什么大多数实现在C++ 03中的全局命名空间中仍然具有cmath函数?

Rus*_*lan 7 c++ namespaces

据我所知,在C++ 03中#include <cmath>必须只声明函数namespace std.从C++ 11开始,它们还可以在全局命名空间中声明.这是大多数C++实现在全局命名空间中声明函数(大概是#includeing <math.h>)的实践的结果,然后就是这样做using ::acos;namespace std.

但在我看来,实现同样容易做到这样的事情<cmath>:

namespace __C_LANGUAGE_MATH_H
{
#include <math.h>
}
// ...
namespace std
{
// ...
using __C_LANGUAGE_MATH_H::acos;
// ...
}
Run Code Online (Sandbox Code Playgroud)

为什么不实践而不仅仅是污染全局命名空间?我建议的解决方案是否有一些主要的缺点使得C++委员会允许在C++ 11中污染全局命名空间?

注意:这确实有效,并且链接器没有错误,至少使用GCC + Binutils-ld.我实际上尝试并编辑了GCC的cmath文件,如下所示,并编译了我的项目,它cmath成功地主动使用了函数(在修复了一些错误未std::在项目中指定的调用之后):

mv /usr/include/c++/5.3.0/cmath{,.bak}
sed -i -e 's@\(# *include <math.h>\)@namespace __C_LANGUAGE_MATH_H\n{\n\1\n}@' \
    -e 's@\(using \+\)::@\1__C_LANGUAGE_MATH_H::@' /usr/include/c++/5.3.0/cmath
Run Code Online (Sandbox Code Playgroud)

dew*_*led 2

正如 gcc bugzilla 中相应问题讨论中所述,由于包含防护,这种方法不允许在 C++ 之后包含 C 标头:

#include <cmath>
#include <math.h> // include skipped by include guards

...
sin(x); // error: no sin in global namespace
Run Code Online (Sandbox Code Playgroud)

正如您提到的,在缺陷报告中发布问题后,对 C 库包装器的标准要求发生了变化,并且从实现的角度来看,以前的要求已被宣布为不切实际。