c – std :: bind() – 从派生类的成员函数中创建基本保护的成员函数

我想从派生类bind()到我的基类的函数的版本.该功能在基地被标记为保护.当我这样做时,代码在Clang(Apple LLVM Compiler 4.1)中高兴地编译,但在g 4.7.2和Visual Studio 2010中都会出现错误.错误是:“Base :: foo”:不能访问受保护的成员“.

这意味着引用的上下文实际上在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 );
    }
};

为什么行为差异?哪个是对的?为错误编译器提供了哪些解决方法

解决方法

答:请参阅 boost::bind with protected members & context引用本标准的这一部分

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() {}
};

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...