为啥 const/non-const 函数重载的继承不明确?

Posted

技术标签:

【中文标题】为啥 const/non-const 函数重载的继承不明确?【英文标题】:Why is inheritance of a const/non-const function overload ambiguous?为什么 const/non-const 函数重载的继承不明确? 【发布时间】:2019-06-12 23:41: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 也是模棱两可的,但有一个可能的函数可以调用。) 标准中有这种行为的原因吗?谢谢!

【问题讨论】:

***.com/questions/5103543/… 【参考方案1】:

当编译器试图在重载决议之前找出名称get 所指的实体时,就会出现歧义。它可以是 A 类或 B 类的函数名称。为了构建重载列表,编译器只需选择其中一个类即可从中提取函数。为了解决这个问题,您可以将该名称从两个基类带入派生类(并将它们公开):

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

【讨论】:

一个令人讨厌的 C++ 小问题! 一项重要的 C++ 保护:如果向基类添加函数会改变重载集,您的代码可能会悄悄地中断;有了这个规则,它就会吵闹。【参考方案2】:

问题是您实际上并没有一个统一的重载集,其中可变变体无疑是最好的,但是 两个不同的重载集,在 A 和 @987654322 @,编译器不会自动合并它们。

using A::get;
using B::get;

C 中合并重载集,从而解决歧义。

【讨论】:

以上是关于为啥 const/non-const 函数重载的继承不明确?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 TypeScript 中没有重载的构造函数实现?

为啥函数重载不提示错误?

为啥这些重载的函数调用模棱两可?

为啥函数不能被返回类型重载? [复制]

为啥 Typescript 不以正确的方式支持函数重载?

在重载时为啥不考虑函数的返回类型? [复制]