-
Notifications
You must be signed in to change notification settings - Fork 786
Description
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?