C++ 为什么函数重载不会导致不明确的错误?(c+;+;)

C++ 为什么函数重载不会导致不明确的错误?(c+;+;),c++,function,overloading,implicit-conversion,C++,Function,Overloading,Implicit Conversion,这段代码在GCC4.6.1和4.8.1中编译时没有错误(eclipse自动编译说:候选代码是:float-pow(float,int)long-double-pow(long-double, int)双功率(双,int)): #包括 #包括 #包括 使用名称空间std; 内部主(空){ 常数i=0,x=2; 双y=功率(i,x); y=对数(i)/对数(x); CUT< P>您不会有任何编译错误,因为C++标准表示您的整数类型将被接受并转换为双。 根据标准§26.8/11: 此外,应具有足够的额

这段代码在GCC4.6.1和4.8.1中编译时没有错误(eclipse自动编译说:候选代码是:float-pow(float,int)long-double-pow(long-double, int)双功率(双,int)):

#包括
#包括
#包括
使用名称空间std;
内部主(空){
常数i=0,x=2;
双y=功率(i,x);
y=对数(i)/对数(x);

CUT< P>您不会有任何编译错误,因为C++标准表示您的整数类型将被接受并转换为双。 根据标准§26.8/11:

此外,应具有足够的额外过载,以确保:
[…]
3.否则,如果与double参数对应的任何参数的类型为double或integer类型,则与double参数对应的所有参数都有效地转换为double

也可以看到上面写着:

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


您没有任何编译错误,因为C++标准表示您的整数类型将被接受并转换为双。 根据标准§26.8/11:

此外,应具有足够的额外过载,以确保:
[…]
3.否则,如果与double参数对应的任何参数的类型为double或integer类型,则与double参数对应的所有参数都有效地转换为double

也可以看到上面写着:

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


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


在您的例子中,答案非常清楚:没有任何版本的pow(a,b)将参数a作为整数接受。编译器不会显示错误,而是尝试查找具有内置(或自定义)参数的pow版本可以将int强制转换为pow期望的类型的类型转换运算符。碰巧有3个这样的函数,每个这样的函数都有一个转换运算符。这就是编译器发现它不明确的原因。

我假设问题是:“为什么函数重载会导致不明确错误?”


在您的例子中,答案非常清楚:没有任何版本的pow(a,b)将参数a作为整数接受。编译器不会显示错误,而是尝试查找具有内置(或自定义)参数的pow版本可以将int转换为pow所期望的类型的类型转换运算符。碰巧有3个这样的函数,每个这样的函数都有一个转换运算符。这就是编译器发现它不明确的原因。

,因为
pow
接受一个
double
float
作为第二个参数(您的
x
).是C++11中对
pow
的描述


如果您在VS2010中运行相同的代码,也会发出错误。

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


如果您在VS2010中运行相同的代码,也会出现错误。

这里的问题是什么?如果有疑问,请信任编译器,忘记eclipseWhat是中间代码你的程序的目标是取悦eclipse,还是被编译?这个程序的目标是理解隐式转换。当然,这只是一个具体问题的荒谬简化。我发现发布数千行代码是双曲线的。问题是:为什么要编译这段代码?这里的问题是什么?如果有疑问,请相信编译器忘记日食什么是中间的你的程序的目标是取悦eclipse,还是被编译?这个程序的目标是理解隐式转换。当然,这只是一个具体问题的荒谬简化。我发现发布数千行代码是夸张的。问题是:为什么要编译这些代码?我相信这实际上是缺陷报告的主题@Benvoig你是说在eclipse中吗?不,我是指规则。如果我理解正确的话,实际上实现它是一个无法维护的模板灾难。而且非常不直观,因为规则与正常的内置转换不一致。这是正确的,可能也是出现类似问题的原因。哦,现在我想我记得了成员。因为遵循规则需要模板才能实际实现,它与用户定义的类型完全匹配,并且用户定义的转换运算符调用不正确。我相信这实际上是缺陷报告的主题。@BenVoigt你是说在eclipse中吗?不,我指的是规则。实际实现它结果是一个失败如果我理解正确的话,这将是一场灾难。也非常不直观,因为规则与正常的内置转换不一致。这是正确的,可能也是出现类似问题的原因。哦,现在我想我记得了。因为遵循规则需要实现模板,所以它将成为一个完美的匹配对于用户定义的类型,以及用户定义的转换运算符调用不正确。
#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;
}