Fedor
Fedor

Reputation: 21357

Can a method be referenced using a child class name in C++?

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

Answers (2)

Davis Herring
Davis Herring

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

Ripi2
Ripi2

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

Related Questions