boost::bind with protected members & context

前端 未结 3 575
不知归路
不知归路 2020-12-17 01:29

In the below code, there are two \"equivalent\" calls to std::for_each using boost:bind expressions. The indicated line compiles, the indicated fai

相关标签:
3条回答
  • 2020-12-17 01:42

    The reason for this restriction is enforcement of access control across different classes that share a common base.

    This is reinforced by notes in Core Language Defects Report defect #385, the relevant part copied here for reference:

    [...] the reason we have this rule is that C's use of inherited protected members might be different from their use in a sibling class, say D. Thus members and friends of C can only use B::p in a manner consistent with C's usage, i.e., in C or derived-from-C objects.

    As an example of something this rule prevents:

    class B {
    protected:
        void p() { };
    };
    
    class C : public B {
    public:
        typedef void (B::*fn_t)();
        fn_t get_p() {
            return &B::p; // compilation error here, B::p is protected
        }
    };
    
    class D : public B { };
    
    int main() {
        C c;
        C::fn_t pbp = c.get_p();
        B * pb = new D();
        (pb->*pbp)();
    }
    

    The protected status of D::p is something we want the compiler to enforce, but if the above compiled that would not be the case.

    0 讨论(0)
  • 2020-12-17 01:55

    Actually, this seems logical. Inheritance gives you access to Derived::foo and not to Base::foo. Let me illustrate with a code example:

    struct Derived : public Base
    {
        void callPrivateMethod(Base &b)
        {
            // this should obviously fail
            b.foo(5);
    
            // pointer-to-member call should also fail
            void (Base::*pBaseFoo) (int) = &Base::foo; // the same error as yours here
            (b.*pBaseFoo)(5);
        }
    };
    
    0 讨论(0)
  • 2020-12-17 01:58

    It's all about "context". In the first call the context of the call is Derived which has access to the protected members of Base and hence is allowed to take addresses of them. In the second the context is "outside of" Derived and hence outside of Base so the protected member access is not allowed.

    0 讨论(0)
提交回复
热议问题