How to call a static method from a private base class?

故事扮演 提交于 2019-12-03 04:29:40

Do this:

struct Derived2: public Derived1 {
    void SomeInstanceMethod(){
        ::Base::SomeStaticMethod();
//      ^^
//      Notice leading :: for accessing root namespace.
    }
};

I think michalsrb's answer is better, but for completeness:

namespace
{
    void SomeStaticMethodProxy()
    {
        return Base::SomeStaticMethod();
    }
}

struct Derived2: public Derived1 {
    void SomeInstanceMethod(){
        SomeStaticMethodProxy();
    }
};

will also work.

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)

[...]The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.[...]

Note that even if you type Base::SomeStaticMethod(), obviously SomeStaticMethod is looked up in Base scope (It's qualified name), but name Base 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 in Derived2, first Derived2 scope is searched, then Derived1 scope is searched and then Base 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 is Base's member which isn't accessible from Derived2.

You can do this if you want to call it through the hierarchy:

struct Derived1: private Base {
protected:
    using Base::SomeStaticMethod;
};

struct Derived2: public Derived1 {
    void SomeInstanceMethod(){
        Derived1::SomeStaticMethod();
    }
};

Otherwise, do as @michalsrb mentioned if you want to call it directly on Base.

A couple of possibilities:

  1. Don't use the inheritance structure to call the method. Use ::Base::SomeStaticMethod() to call it. Base is accessible in the global namespace.

  2. Bring the private function into the namespace of Derived1 by writing using Base::SomeStaticMethod;

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!