std :: bind() - 从派生类的成员函数中获取基本保护的成员函数 [英] std::bind()-ing a base protected member function from a derived class's member function
问题描述
我想要 bind()
到我的基类的派生类的函数版本。该功能在基座中标记为受保护。当我这样做,代码编译在Clang(苹果LLVM编译器4.1),但是在g ++ 4.7.2和Visual Studio 2010中的错误。错误是沿着这样的线:'Base :: foo':can not访问保护成员。
这意味着引用的上下文实际上在 bind()
当然这个功能被看作是受保护的。但不应该 bind()
继承调用函数的上下文 - 在这种情况下, Derived :: foo()
以下程序说明了这个问题。
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); //法律但不必要。
fn(this);
auto fn2 = std :: bind(& Base :: foo,
std :: placeholders :: _ 1); // ILLEGAL在G ++ 4.7.2和VS2010。
fn2(this);
}
};
为什么行为不一致?哪个是对的?
答案:参见 boost :: bind with protected members&上下文,引用标准的这部分
除了前面第11节中描述的附加访问检查,
是当非静态数据成员或非静态成员函数
是其命名类(11.2)的受保护成员时应用)如早前描述的
,授予对受保护成员的访问,因为引用
发生在某个类C的朋友或成员中。如果访问是形成
a指向成员的指针(5.3.1),嵌套名称说明符应该命名为C或
a类派生自C。所有其他访问涉及一个(可能
隐式)对象表达式(5.2.5)。在这种情况下,
对象表达式的类应为C或从C派生的类。
解决方法:make foo
a public
成员函数
code> #include< functional>
struct base
{
public:virtual void foo(){}
};
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?
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() {}
};
这篇关于std :: bind() - 从派生类的成员函数中获取基本保护的成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!