Reputation: 21357
Please consider a struct A
with a method f
, and an inherited struct B
, which does not redefine f
. In this case B::f
refers to the same method as A::f
.
Is it allowed to invoke the method f
of an A
object using B::f
name as in the following example?
struct A { void f() {} };
struct B : A {};
int main() { A{}.B::f(); }
Clang and GCC diverge here. Clang is fine with the program, while GCC prints the error:
error: 'B' is not a base of 'A'
demo: https://gcc.godbolt.org/z/Pn7jehzdP
Which compiler is right here according to the standard?
Upvotes: 14
Views: 363
Reputation: 40053
GCC is correct: [class.access.base]/6 requires that a pointer to the left-hand operand of .
be able to be
implicitly converted to a pointer to the naming class of the right operand.
The term "naming class" is defined in [class.access.general]/5; in your example it is B
, and obviously an A*
cannot be implicitly converted to a B*
.
The placement of the rule is counterintuitive for this particular case that has no non-public members or inheritance.
Upvotes: 7
Reputation: 7198
Is it allowed to invoke the method f of an A object using B::f name as in the following example?
struct A { void f() {} };
struct B : A {};
int main() { A{}.B::f(); }
A{}.B::f()
tries to build an object of type A
. Then call its member B::f
This the error, because A knows nothing about B.
If you want to call a base member from a derived class them normally you just use D d;
d.f();
In your case, use B{}.A::f()
Be aware that calling a base method like this will break virtual ways.
Upvotes: 1