这意味着引用的上下文实际上在bind()中,当然这个函数被看作是受保护的.但是,不应该bind()继承调用函数的上下文 – 在这种情况下,Derived :: foo() – 因此可以看到base方法是可访问的?
以下程序说明了这个问题.
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 );
}
};
为什么行为差异?哪个是对的?为错误编译器提供了哪些解决方法?
解决方法
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.
解决方法:使foo成为公共成员函数
#include <functional>
struct Base
{
public: virtual void foo() {}
};