Due to the layout of a third-party library, I have something like the following code:
struct Base
{
static void SomeStaticMethod(){}
};
struct Derived1: private Base {};
struct Derived2: public Derived1 {
void SomeInstanceMethod(){
Base::SomeStaticMethod();
}
};
int main() {
Derived2 d2;
d2.SomeInstanceMethod();
return 0;
}
I'm getting compiler error C2247 with MSVC:
Base::SomeStaticMethod not accessible because Derived1 uses private to inherit from Base.
I know I can't access Base
members from Derived2
via inheritance because of the private specifier, but I should still be able to call a static method of Base
- regardless of any inheritance relationship between Base
and Derived2
.
How do I resolve the ambiguity and tell the compiler I'm just making a call to a static method?
Other answers provide way to solve the problem, I'll try to explain what's happening. It's because of injected-class-name.
9.2 (N4594)
Note that even if you type
Base::SomeStaticMethod()
, obviouslySomeStaticMethod
is looked up inBase
scope (It's qualified name), but nameBase
itself also has to be looked up somehow, (In this example as an unqualified name (because it does not appear after scope resolution operator))What happens is that when you search for (unqalified) name
Base
inDerived2
, firstDerived2
scope is searched, thenDerived1
scope is searched and thenBase
scope is searched and finally injected-class-name is found. Then access control takes place (because access control takes place after name lookup) and it'll find that name you looked up isBase
's member which isn't accessible fromDerived2
.Do this:
A couple of possibilities:
Don't use the inheritance structure to call the method. Use
::Base::SomeStaticMethod()
to call it.Base
is accessible in the global namespace.Bring the
private
function into the namespace ofDerived1
by writingusing Base::SomeStaticMethod;
You can do this if you want to call it through the hierarchy:
Otherwise, do as @michalsrb mentioned if you want to call it directly on
Base
.I think michalsrb's answer is better, but for completeness:
will also work.