我有一个相当大的应用程序,我在没有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 ++编译器
由于
答案 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
版本,但遗憾的是没有可靠的方法来强制执行,所以你只需要仔细检查这个特定的雷区。