Please see this 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 prints base while Clang prompts an error diagnosis. In the current draft, the relevant rule is defined like that:
If a virtual member function F is declared in a class B, and, in a class D derived (directly or indirectly) from B, a declaration of a member function G corresponds ([basic.scope.scope]) to a declaration of F, ignoring trailing requires-clauses, then G overrides F.
Simultaneously, the rule for defining two declarations who correspond is defined like that:
Two declarations correspond if they (re)introduce the same name, both declare constructors, or both declare destructors, unless
- [...]
- each declares a function or function template, except when
- both declare functions with the same parameter-type-list, equivalent ([temp.over.link]) trailing requires-clauses (if any, except as specified in [temp.friend]), and, if both are non-static members, the same cv-qualifiers (if any) and ref-qualifier (if both have one), or
In this example, #1 and #2 have the same parameter-type-list, #1 has one ref-qualifier while #2 does not have, hence the latter restriction could be ignored, hence, for these two declarations, we could say they correspond. Hence, #2 overrides #1 that is declared as a virtual function. Hence, we could say both GCC and Clang have the wrong result.
However, in the c++20 standard, the restriction for how to determine a declaration declared in the derived class overrides the virtual function declared in the base class is:
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf overrides Base::vf.
It's obvious that the current rule has changed its original meaning. Is it a defect in the new rule? Or, it's just the artificial design?
Please see this example
GCC prints
basewhile Clang prompts an error diagnosis. In the current draft, the relevant rule is defined like that:Simultaneously, the rule for defining two declarations who correspond is defined like that:
In this example,
#1and#2have the same parameter-type-list,#1has one ref-qualifier while#2does not have, hence the latter restriction could be ignored, hence, for these two declarations, we could say they correspond. Hence,#2overrides#1that is declared as a virtual function. Hence, we could say both GCC and Clang have the wrong result.However, in the c++20 standard, the restriction for how to determine a declaration declared in the derived class overrides the virtual function declared in the base class is:
It's obvious that the current rule has changed its original meaning. Is it a defect in the new rule? Or, it's just the artificial design?