std :: bind() - 从派生类的成员函数中获取基本保护的成员函数 [英] std::bind()-ing a base protected member function from a derived class's member function

查看:710
本文介绍了std :: bind() - 从派生类的成员函数中获取基本保护的成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆