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

时间:2014-01-03 12:08:00

标签: c++ g++ trigonometry cos

我有一个相当大的应用程序,我在没有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和罪是std不是吗?

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

由于

2 个答案:

答案 0 :(得分:8)

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

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

这是一种没有实现库的明显方法 必须重写所有内容,只是为了在C ++中使用它,以及它 将导致所有名称也出现在全球 命名空间。

形式上,这是一个C ++ 11功能; pre-C ++ 11需要它 <cmath>仅将符号引入std::。几乎, 所有,或者至少大多数实现都做了类似的事情 以上,并且非法地将它们引入全球 命名空间,所以C ++ 11改变了标准以反映现实。

答案 1 :(得分:6)

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

你应该总是使用std版本,但遗憾的是没有可靠的方法来强制执行,所以你只需要仔细检查这个特定的雷区。