【问题标题】:C++ Cosine works without the std namespace - Why? [duplicate]C++ 余弦在没有 std 命名空间的情况下工作 - 为什么? [复制]
【发布时间】:2014-01-03 12:07:59
【问题描述】:

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

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

谢谢

【问题讨论】:

标签: c++ g++ trigonometry


【解决方案1】:

当您包含&lt;cmath&gt; 时,所有函数都在 std::。对于 C 头文件,还有一个特殊规则,即 允许(但不要求)实现使它们 在全局命名空间中可见;这是因为大多数 实现将简单地适应 C 标头,例如:

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

这是实现库的一种明显方式,无需 必须重写一切,只是为了在 C++ 中拥有它,而且它 将导致所有名称也出现在全局中 命名空间。

正式地说,这是一个 C++11 特性; C++ 11 之前的版本要求 &lt;cmath&gt; 只将符号引入std::。几乎, 所有,或者至少大多数实现都做了类似的事情 上面,并且确实将它们非法地引入了全球 命名空间,因此 C++11 更改了标准以反映现实。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 在某些情况下,只有一些重载可用这一事实很好(我已经忘记了,虽然我已经被它咬住了)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2023-03-06
    相关资源
    最近更新 更多