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?
No you can't. The annotation Override is optional, thus even not explicitly declaring it on child class' method, it will automatically override the parent version of the method.
Yes, It is allowed to define a method with the same name as that of a class. There is no compile-time or runtime error will occur.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With