Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::bind()-ing a base protected member function from a derived class's member function

I want to bind() to my base class's version of a function from the derived class. The function is marked protected in the base. When I do so, the code compiles happily in Clang (Apple LLVM Compiler 4.1) but gives an error in both g++ 4.7.2 and in Visual Studio 2010. The error is along the lines of: "'Base::foo' : cannot access protected member."

The implication is that the context for the reference is actually within bind(), where of course the function is seen as protected. But shouldn't bind() inherit the context of the calling function--in this case, Derived::foo()--and therefore see the base method as accessible?

The following program illustrates the issue.

struct Base
{
protected: virtual void foo() {}
};

struct Derived : public Base
{
protected:
    virtual void foo() override
    {
        Base::foo();                        // Legal

        auto fn = std::bind( &Derived::foo, 
            std::placeholders::_1 );        // Legal but unwanted.
        fn( this );

        auto fn2 = std::bind( &Base::foo, 
            std::placeholders::_1 );        // ILLEGAL in G++ 4.7.2 and VS2010.
        fn2( this );
    }
};

Why the discrepancy in behavior? Which is correct? What workaround is available for the error-giving compilers?

like image 930
OldPeculier Avatar asked Jan 24 '13 19:01

OldPeculier


People also ask

Can a protected function be called in derived class?

Protected members that are not declared as static are accessible to friends and member functions in a derived class only through a pointer to, reference to, or object of the derived class.

How do you call a protected member function in C++?

The code snippet for this is given as follows. class Base { protected : int num = 7; }; class Derived : public Base { public : void func() { cout << "The value of num is: " <<< num; } }; In the function main(), the object obj of class Derived is created. Then the function func() is called.

How are protected members of class accessed in the derived class?

If a class is derived privately from a base class, all protected base class members become private members of the derived class. Class A contains one protected data member, an integer i . Because B derives from A , the members of B have access to the protected member of A .

What is protected member in C++?

A pointer to a directly or indirectly derived class. A reference to a directly or indirectly derived class. An object of a directly or indirectly derived class.


1 Answers

Answer: see boost::bind with protected members & context which quotes this part of the Standard

An additional access check beyond those described earlier in clause 11 is applied when a non-static data member or nonstatic member function is a protected member of its naming class (11.2)105) As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C. If the access is to form a pointer to member (5.3.1), the nested-name-specifier shall name C or a class derived from C. All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall be C or a class derived from C.

Workaround: make foo a public member function

#include <functional>

struct Base
{
public: virtual void foo() {}
};
like image 111
TemplateRex Avatar answered Oct 02 '22 22:10

TemplateRex