C++余弦在没有 std 命名空间的情况下工作 - 为什么

C++ Cosine works without the std namespace - Why?

本文关键字:情况下 工作 为什么 命名空间 std 余弦 C++      更新时间:2023-10-16

我有一个相当大的应用程序,我在没有 std 命名空间的情况下工作,我注意到我没有包含 std::cos 或 std::sin,但我得到了正确的结果。为什么?

一些精简代码的示例是:

#include <ctime>
#include <cmath>
#include <iostream>
#include <vector>
//#include <unistd.h>
#include <fstream>
#include <sstream>
#include <iomanip>
using std::cout;
using std::endl;
int main()
{
    double pi = 4*(atan(1));
    cout << "pi = " << pi << endl
         << "cos(pi) = " << cos(pi) << endl
         << "sin(pi) = " << sin(pi) << endl;

    return 0;
}

我保留了所有标题,我在主代码中使用它们。输出按预期返回 ~3.14、-1 和 1e-16。为什么会这样?cos和罪恶在性病中,不是吗?

我在远程 unix 服务器上使用 g++ 编译器

谢谢

当你包含 <cmath> 时,所有函数都声明在 std:: . 对于 C 标头,还有一个特殊规则,即允许(但不需要)实现使它们在全局命名空间中可见;这是因为大多数实现将简单地调整 C 标头,如下所示:

#include <math.h>
namespace std
{
    using ::sin;
    using ::cos;
    // ...
}

这是实现库的明显方法,无需必须重写所有内容,只是为了将其放在C++中,并且它将导致所有名称也存在于全局命名空间。

从形式上讲,这是一个 C++11 功能;C++11 之前的要求 <cmath>只将符号引入std::. 几乎所有,或者至少大多数实现都做了类似以上,并且确实将它们非法引入全球因此C++11改变了标准以反映现实。

不幸的是,库实现被允许将名称从 C 库转储到全局命名空间中,以及 std ,并且许多都这样做。更糟糕的是,在某些情况下,全局命名空间中只有一些重载可用,如果不指定std版本,则会导致意外的精度损失。

您应该始终使用std版本,但遗憾的是,没有可靠的方法来强制执行,因此您只需要小心翼翼地穿过这个特定的雷区。