"sqrt"不是"std"的成员。

26

我在Linux上编译我的程序 - 它有以下代码行:

std::sqrt((double)num);

在Windows上没问题,但是在Linux上出错了:

sqrt 不是 std 的成员

我已经包含了 math.h,这是什么问题呢?


5
你有包含 <cmath> 吗? - juanchopanza
2
返回已翻译的文本: #include <cmath>, 根据 http://en.cppreference.com/w/cpp/numeric/math/sqrt - hmjd
我在Windows和Linux上观察到了相同的差异。 - user3405291
2个回答

36

将指令更改为#include <cmath>。 C++头文件的形式为<cxxxxxxx>,保证在std命名空间中具有标准名称(并且可以选择在全局命名空间中提供它们)。<xxxxxx.h>则不一定。


1
在C++11之前,保证std命名空间中具有标准名称。当然,之所以在C++11中对此进行了放宽,是因为有些实现从未费心过这一点。 - BoBTFish
5
在 C++ 中,std 命名空间中的标准名称是有保证的。在 C++11 之前,这些名称不会在全局命名空间中出现。但是,C++11 允许它们同时存在于全局命名空间中,因为这是最普遍的现有实践。 - James Kanze
1
@BoBTFish,参考JamesKanze所说的,查看17.6.1.2/4。 - jrok
1
对不起,我之前发布了没有确认的内容。我不会删除它,那样会让后续的评论变得混乱。 - BoBTFish

6
这是因为<math.h>并没有在namespace std中声明函数。它仅被包含在C++标准中以保持兼容性。正确的C++ include应该是<cmath>
每个C头文件,其名称形式为name.h,都会将相应cname头文件中放置在标准库命名空间中的每个名称视为放置在全局命名空间范围内。未指定这些名称首先是否在命名空间std的命名空间范围内声明或定义,然后通过显式using-declarations注入到全局命名空间范围内。
你的代码在Windows下能工作仅仅是纯属运气。最后一句话提示了在Windows下可能会发生但不会在Linux下发生的事情:显然,在Windows下,这些名称在全局命名空间和命名空间std中都是有效的。

<math.h>是标准C的一部分,作为“兼容性特性”。实际上,在某些情况下,有很好的理由优先选择它。当然,它声明了::sqrt而不是std::sqrt - James Kanze
@JamesKanze 感谢您的纠正,我之前不知道这一点。我已经修改了我的回答。 - Arne Mertz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接