C++ std::bind()-从派生类';s成员函数
我想从派生类将()绑定到我的基类版本的函数。该功能在底座中标记为受保护。当我这样做时,代码在Clang(Apple LLVM Compiler 4.1)中编译得很愉快,但在g++4.7.2和Visual Studio 2010中都出现了错误。错误大致如下:“'Base::foo':无法访问受保护的成员。” 这意味着引用的上下文实际上在C++ std::bind()-从派生类';s成员函数,c++,c++11,protected,derived-class,stdbind,C++,C++11,Protected,Derived Class,Stdbind,我想从派生类将()绑定到我的基类版本的函数。该功能在底座中标记为受保护。当我这样做时,代码在Clang(Apple LLVM Compiler 4.1)中编译得很愉快,但在g++4.7.2和Visual Studio 2010中都出现了错误。错误大致如下:“'Base::foo':无法访问受保护的成员。” 这意味着引用的上下文实际上在bind()中,其中函数当然被视为受保护的。但是bind()是否应该继承调用函数的上下文(在本例中是Derived::foo()),从而将基方法视为可访问的 以下程
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 ); // Legal but unwanted.
fn( this );
auto fn2 = std::bind( &Base::foo,
std::placeholders::_1 ); // ILLEGAL in G++ 4.7.2 and VS2010.
fn2( this );
}
};
为什么行为上存在差异?哪个是正确的?给出错误的编译器有什么解决方法?回答:请参阅标准中引用的这一部分
除第11条前面所述之外的额外访问检查
当非静态数据成员或非静态成员函数
是其命名类(11.2)105)的受保护成员,如所述
在此之前,由于引用
发生在某个C类的朋友或成员中。如果要访问窗体
一个指向构件(5.3.1)的指针,嵌套名称说明符应命名为C或
从C派生的类。所有其他访问都涉及
隐式)对象表达式(5.2.5)。在本例中
对象表达式应为C或从C派生的类
解决方法:使foo
apublic
成员函数
#include <functional>
struct Base
{
public: virtual void foo() {}
};
#包括
结构基
{
public:virtualvoid foo(){}
};
这与bind
无关。由于已经引用了标准@rhalbersma,因此在任何上下文中,&Base::foo
表达式在派生的
的非友好成员中都是非法的
但是如果您的目的是做一些与调用Base::foo()等价的事情代码>,您有一个更大的问题:指向成员函数的指针总是调用虚拟重写
#include <iostream>
class B {
public:
virtual void f() { std::cout << "B::f" << std::endl; }
};
class D : public B {
public:
virtual void f() { std::cout << "D::f" << std::endl; }
};
int main() {
D d;
d.B::f(); // Prints B::f
void (B::*ptr)() = &B::f;
(d.*ptr)(); // Prints D::f!
}
#包括
B类{
公众:
虚拟void f(){std::coutDerived::foo
调用自身是故意的,还是仅仅是简化为一个例子的结果?@aschepler这是“legal but underfect”中“不需要的”部分。如果您不能更改Base
,请使用派生方法(例如,void basefoo(){Base::foo();}
)令人惊讶和困惑地在VisualC++(Express 2010)中,你可以使用<代码>和派生::Boo::Foo绕过这个错误,但是它基本上忽略了你的第二个参数(即它总是使用<代码>这个/<代码>)。