【问题标题】:C++ cmath pow error present in older version of the compiler, but not on the newer one旧版本的编译器中存在 C++ cmath pow 错误,但新版本中没有
【发布时间】:2012-02-14 08:55:38
【问题描述】:

使用 4.2.1 g++ 编译器出现以下错误:

functions.cpp:24: error: call of overloaded ‘pow(long int&, long int&)’ is ambiguous
/usr/include/architecture/i386/math.h:343: note: candidates are: double pow(double, double)
/usr/include/c++/4.2.1/cmath:373: note:                 long double std::pow(long double, int)
/usr/include/c++/4.2.1/cmath:369: note:                 float std::pow(float, int)
/usr/include/c++/4.2.1/cmath:365: note:                 double std::pow(double, int)
/usr/include/c++/4.2.1/cmath:361: note:                 long double std::pow(long double, long double)
/usr/include/c++/4.2.1/cmath:357: note:                 float std::pow(float, float)

这是负责的代码:

long power(long a, long b) {
    if (b < 0) return 0;
    return pow(a,b);
}

但是,在我的 4.6.1 版本中,我使用两个 longs 进行 pow 评估的代码没有错误或警告(即使使用 -Wextra 标志)。 为什么是这样?对pow 函数使用两个long 是我的错误吗?

【问题讨论】:

  • 看起来像 4.6 添加了 pow(long,long) 作为扩展
  • 标准说应该是double pubs.opengroup.org/onlinepubs/9699919799/functions/pow.html所以我相信只要坚持标准就可以了,只要做个演员表就好了。
  • Anycorn,您能否提供参考(将其作为答案发布)
  • 我不能——标准没有提到pow(long,long)——因此我认为它是一个扩展。
  • 您的工作做得很好,指出了编译中的差异!

标签: c++


【解决方案1】:

据我所知,pow 未被 ANSI 确认支持long, long 作为参数。请考虑使用双精度(或强制转换),如果需要,将结果舍入如下:

long int result = llround(pow((double)2L, (double)4L));

【讨论】:

    【解决方案2】:

    问题在于没有将两个 long 作为参数的 pow 定义。正因为如此,longs 将被转换为其他数据类型,但这种转换会导致歧义,因为有许多可能的转换方式。 gcc 不知道如何解释调用,所以它会给你一个错误。

    【讨论】:

    • 我明白这一点。但是为什么旧版本的编译器有问题,而新版本的没有问题?
    • 可能是较新的版本将调用映射到兼容的方法。例如,它可能有一些类型转换的约定。它可能会将 long 转换为 double,以免失去精度。
    【解决方案3】:

    Pow 只支持 double 而不是 long。 也许在较新的版本中,他们添加了一个隐式强制转换来从 long 加倍。这是我能想到的最好的。 我还没有听说过将支持扩展到长期战俘!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 2013-05-03
      相关资源
      最近更新 更多