微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何覆盖虚函数的要求是否已更改?

如何解决如何覆盖虚函数的要求是否已更改?

请参阅此example

#include <iostream>
class B{
public:
    virtual void fun() &{  //#1
        std::cout<<"base\n";
    }
};
class A:public B{
public:
  void fun(){  //#2
      std::cout<<"override\n";
  }
};
int main(){
   A  a;
   B* ptr = &a;
   ptr->fun();
}

GCC 打印 base,而 Clang 提示错误诊断。在目前的草案中,相关规则是这样定义的:
[class.virtual#2]

如果在类 B 中声明了虚拟成员函数 F,并且在从 B 派生(直接或间接)的类 D 中,则声明了一个成员函数 G 对应([basic.scope.scope] ) 到 F 的声明,忽略尾部的 requires 子句,然后 G 覆盖 F

同时,定义两个对应的声明的规则是这样定义的:
[basic.scope#scope-3]

如果两个声明(重新)引入相同的名称、都声明构造函数或都声明析构函数,则它们是对应的,除非

  • 两者都声明具有相同参数类型列表的函数,等价的 ([temp.over.link]) 尾随 requires 子句(如果有,除非在 [temp.friend] 中指定),并且,如果两者都不是-静态成员,相同的 cv 限定符(如果有)和引用限定符(如果两者都有),或

在这个例子中,#1#2 具有相同的参数类型列表,#1一个引用限定符而 #2 没有,因此后者可以忽略限制,因此,对于这两个声明,我们可以说它们是对应的。因此,#2 覆盖了声明为虚函数#1。因此,如果我们遵守当前的草案,我们可以说 GCC 和 Clang 的结果都是错误的。

但是,在c++20标准中,对于如何确定派生类中声明的声明是否覆盖基类中声明的虚函数的限制是:
[class.virtual#2]

如果在类 Base 和类 Derived 中声明虚拟成员函数 vf,直接或间接从 Base 派生,则成员函数 vf 具有相同的名称,参数类型列表([dcl.fct ])、cv-qualification 和 ref-qualifier(或没有相同的),因为 Base :: vf 被声明,然后 Derived :: vf 覆盖 Base :: vf。

很明显,现在的规则已经改变了它的原意。这是新规则的缺陷吗?或者,只是人为的设计使需求被改变?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。