When compiling the following example in msvc, I get
'Interface' not accessible because 'Base' uses 'private' to inherit from 'Interface'
in the line marked with Error
. When the call to foo
is qualified with a type alias of the same type, it works. I tested with msvc and ideone.
Why are the two calls not equal?
struct Interface {};
template<class T>
struct Base : private T
{
void foo() {}
};
using BaseX = Base<Interface>;
class Derived : Base<Interface>
{
Derived() {
Base<Interface>::foo(); // Error
BaseX::foo(); // Works
}
};
Ideone
Injected-class-names.
The name Interface
is injected into the scope of the class Interface
as if it's a public member, and in turn inherited by Base<Interface>
(as a private member, since you are using private inheritance).
When you write Base<Interface>::foo()
in Derived
, unqualified name lookup for Interface
looks first at Derived
and its base class, finds Interface
in the base class, and then access control kicks in because that name is private
.
The simplest fix is to just write Base::foo()
, or even just foo()
if it isn't virtual and you aren't planning to write a foo()
in Derived
.
If you have to include the template argument for some reason, then write Base<::Interface>
.
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