为什么const和non-const函数重载的继承会产生歧义?

20

我试图创建两个类,第一个类具有非const实现的函数,第二个类具有const实现。这里是一个小例子:

class Base {
protected:
  int some;
};

class A : public virtual Base {
  const int& get() const {
    return some;
  }
};

class B : public virtual Base {
  int& get() {
    return some;
  }
};

class C : public A, B {};

C test;
test.get(); // ambiguous 

get 函数的调用是有歧义的。尽管 const 版本需要满足更多的要求。(在 const C 上调用 get 也是有歧义的,但是有一个可以调用的函数。) 标准中这种行为是否有原因?谢谢!


https://dev59.com/hG435IYBdhLWcg3w-lT2 - Jesper Juhl
2个回答

19

当编译器在重载解析之前尝试确定名称get指代的实体时,就会出现歧义。它可以是来自类A或类B的函数名称。为了构建超载列表,编译器需要选择一个类来提取函数。为了修复它,您可以将基类中这个名字的定义都带到派生类中(并使其公共):

class C : public A, public B { public: using A::get; public: using B::get; };

2
一个令人烦恼的 C++ 小问题! - Lightness Races in Orbit
11
一项重要的C++保护措施:如果将函数添加到基类会改变函数的重载集,那么您的代码可能会悄悄出现问题;但使用这个规则,它会发出嘈杂的错误提示来防止这种情况的发生。 - Pete Becker

14
问题在于你实际上没有一个统一的重载集,在其中可变变体将明显是最佳选择,而是两个不同的重载集,在A和B中,并且编译器不会自动合并它们。请翻译:Put
using A::get;
using B::get;

C 中合并重载集以解决歧义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接