【问题标题】:VS 2010 : 2 overloads have similar conversionsVS 2010:2 个重载有类似的转换
【发布时间】:2012-08-24 00:00:04
【问题描述】:

我不明白这里发生了什么

class A{};
class B : A {};

void func(A&, bool){}
void func(B&, double){}

int main(void)
{
    B b;
    A a;
    bool bo;
    double d;

    func(b, bo);
}

编译时,Visual 2010 在func(b, bo); 行给我这个错误

2 overloads have similar conversions
could be 'void func(B &,double)'
or       'void func(A &,bool)'
while trying to match the argument list '(B, bool)'

我不明白为什么 bool 参数不足以解决过载问题。 我见过this question,正如在接受的答案中指出的那样,bool 应该更喜欢 bool 重载。就我而言,我看到第一个参数不足以选择好的功能,但是为什么第二个参数不能解决歧义呢?

【问题讨论】:

  • 奇怪,尤其是因为隐式转换受到限制(私有继承)。
  • 不是第一个参数不够选好的功能;就是第一个参数选择第二个函数,第二个参数选择第一个函数。所以没有一个被选中。

标签: c++ overloading


【解决方案1】:

重载规则比您想象的要复杂一些。您分别查看每个参数并选择该参数的最佳匹配。然后,如果恰好有一个重载为每个参数提供最佳匹配,那就是被调用的那个。在示例中,第一个参数的最佳匹配是func 的第二个版本,因为它只需要将B 转换为B&func 的另一个版本需要将B 转换为B&,然后将B& 转换为A&。对于第二个参数,func 的第一个版本是最佳匹配,因为它不需要转换。第一个版本有第二个参数的最佳匹配,但它没有第一个参数的最佳匹配,所以不考虑它。同样,第二个版本对第一个参数有最佳匹配,但对第二个参数没有最佳匹配,因此不予考虑。现在已经没有func的版本了,调用失败了。

【讨论】:

  • +1 简洁明了,除了语句“它只需要将B 转换为B&” 是不正确的。我不认为这是一个转换
  • 另外,"要求将 B 转换为 B&,然后将 B& 转换为 A&" 没有意义。请注意,C++ 不允许链式转换(例如 X 到 Y 到 Z)。
  • @Nawaz - 标准对重载的讨论包括身份“转换,正如我刚刚发现的那样,它是适用于 BB& 的“转换”,尽管它也被列出作为“没有转换”。
  • @Nawaz - 该标准确实允许链式转换。一个转换序列中的用户自定义转换的次数是有限制的,但没有限制只能转换一次。例如,对于具有 operatorB& 的类,可以应用用户定义的到 B& 的转换,然后将 B& 转换为 A&(在更复杂的继承层次结构中,这可能不是空操作)。实际上,选择重载函数的规则是用“转换序列”来写的。
【解决方案2】:

重载解决规则比 Pete Becker 写的还要复杂。 对于f的每个重载,编译器不仅会计算需要转换的参数数量,还会计算转换的等级。

排名 1

无需转换

左值到右值的转换

数组到指针的转换

函数到指针的转换

资格转换

排名 2

整体促销

浮点促销

排名 3

积分转换

浮点转换

浮点-积分转换

指针转换

指向成员转化的指针

布尔转换

假设所有候选函数都是非模板函数,一个函数当且仅当它有一个参数,该参数的排名优于其他候选者中相同参数的排名,并且其他参数的排名不差。

现在让我们看看 OP 案例。

  • func(A&, bool):第一个参数的转换 B&->A&(排名 3), 第二个参数的完全匹配(排名 1)。
  • func(B&, double):第一个参数完全匹配(排名 1),第二个参数转换 bool->double(排名 3)。

结论:没有人获胜。

【讨论】:

  • 嗯,是的,为了初学者的利益,我省略了细节。
猜你喜欢
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多