【问题标题】:porting isnan to c++11将 isnan 移植到 c++11
【发布时间】:2019-05-22 18:18:12
【问题描述】:

当我将编译器版本从 gcc 4.6 切换到 gcc 4.8 时,我收到以下错误 错误:重载 'isnan(double)' 的调用不明确。

这是因为在 c++11 中有不同的函数声明: C:int isnan(双) C++11: bool isnan(double)

来自cpluplus

  • 在 C 中,这被实现为返回 int 值的宏。 x 的类型应为 float、double 或 long double。
  • 在 C++ 中,它通过每个浮点类型的函数重载来实现,每个都返回一个 bool 值。

我该如何解决这个问题?

【问题讨论】:

  • 你怎么称呼它?向我们展示上下文。
  • juanchoupanza 建议有效。我之前已经声明了 using namespace std,但无论如何我都必须将它添加到 isnan 调用中,因为它是歧义的来源。
  • 这正是use namespace std 的问题所在。
  • 愿此作为一个教训。现在去停止abusing namespace std

标签: c++ c++11


【解决方案1】:

虽然你可以通过不到处说using namespace std;来缓解这个问题,但你可以通过明确使用std::isnan来避免它:

#include <cmath>
#include <iostream>

int main()
{
  double x = ....;
  std::cout << std::boolalpha;
  std::cout << std::isnan(x) << std::endl;
}

【讨论】:

  • 这种方法肯定行得通,但不适合在大型代码库中删除“using namespace std”,因为它可能需要太多更改。
  • @wazza 这比让代码被破坏更合适。 using namespace std; 是一个麻烦的秘诀。我认为花时间从代码中清除它是值得的。
【解决方案2】:

在 C++11 中,C 和 C++ isnan 函数之间不应有歧义。它按预期工作,即使使用using namespace std

请检查您是否没有同时使用#include &lt;math.h&gt;#include &lt;cmath&gt;。只包括 cmath。

或者,也许您在项目中的某个地方有一个用户定义的isnan(double) 函数,或者某些标头包含“math.h”。

另外请注意,如果要编写通用代码,在数学函数上使用“std::”前缀是不正确的,因为它会破坏参数相关查找 (ADL)。 (因为 C++ 标准不允许在 std:: 命名空间中注入函数)

在泛型代码中isnan 的正确用法是using std::isnan;,然后在变量上只使用isnan。否则,您的代码具有用户定义的浮点类型(例如任意精度、自动微分等)将无法正常工作。这种不一致的根源在于,诸如double 之类的内置类型不驻留在命名空间std 中,但对它们进行操作的函数却驻留。

【讨论】:

  • 只是&lt;cmath&gt;,不是&lt;cmath.h&gt;
猜你喜欢
  • 2022-01-23
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2010-10-13
相关资源
最近更新 更多