【问题标题】:Why function overloading causes no ambiguous error? ( c++ )为什么函数重载不会导致模棱两可的错误? (c++)
【发布时间】:2013-06-23 20:05:12
【问题描述】:

此代码在 gcc 4.6.1 和 4.8.1 中编译没有错误(eclipse 自动编译说:候选者是:float pow(float, int) long double pow(long double, int) 双 pow(double, int) ):

#include <iostream>
#include <cmath>
#include <vector>
using namespace std;

int main(void) {
    const int i = 0, x = 2;
    double y = pow( i, x );
    y = log( i ) / log( x );
    cout << y;
return 0;
}

非常感谢。这段代码在工作中做了一些很好的混淆。编译器可信吗?

【问题讨论】:

  • 这里有什么问题?
  • 如有疑问,请相信编译器并忘记 eclipse
  • 你的程序的(中间)目标是什么,取悦eclipse,还是被编译?
  • 这个程序的目标是理解隐式转换。当然,这只是对具体问题的荒谬简化。我发现发布数千行代码有点夸张。问题是:为什么要编译这段代码?

标签: c++ function overloading implicit-conversion


【解决方案1】:

您不会遇到任何编译错误,因为 C++ 标准规定您的整数类型将被接受并转换为双精度。

来自标准 §26.8/11:

此外,应有足够的额外重载以确保:
[...]
3. 否则,如果任何与 double 形参对应的实参为 double 类型或整数类型,则所有与 double 形参对应的实参都被有效地强制转换为 double。

另请参阅cppreference.com/.../pow 上面写着:

如果任何参数具有整数类型,则将其强制转换为 double。

【讨论】:

  • 我相信这实际上是缺陷报告的主题。
  • @BenVoigt 你的意思是在日食中?
  • 不,我是说规则。如果我理解正确的话,实际上实现它是一场无法维护的模板灾难。也很不直观,因为规则与正常的内置转换不一致。
  • 没错,也可能也是出现此类问题的原因。
  • 哦,现在我想我记得了。因为遵循规则需要模板来实际实现,它成为用户定义类型的完美匹配,并且用户定义的转换运算符没有被正确调用。
【解决方案2】:

我假设问题是:“为什么函数重载会导致歧义错误?”。

在您的情况下,答案非常明确:没有任何版本的 pow(a, b) 接受参数 a 作为整数。编译器不会显示错误,而是尝试查找具有内置(或自定义)类型转换运算符的 pow 版本,该运算符可以将 int 转换为 pow 期望的类型。碰巧有 3 个这样的函数,每个这样的函数都有一个转换运算符。这就是为什么编译器会觉得它模棱两可。

【讨论】:

    【解决方案3】:

    因为pow 接受doublefloat 作为第二个参数(您的x)。 Here 是 C++11 中 pow 的描述。

    如果你在VS2010中运行同样的代码也会报错。

    【讨论】:

      猜你喜欢
      • 2018-03-02
      • 2013-05-23
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多