Mal*_*ous 2 c++ inheritance boost
我试图用来boost::bind调用类中的成员函数.通常这样可以正常工作,但在这种特殊情况下,我的编译器(GCC)抱怨我正在尝试使用不可访问的基类,而不是.
这是一些演示此问题的代码.我究竟做错了什么?
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
class base
{
protected:
void test()
{
std::cout << "base::test()\n";
}
};
class derived: virtual protected base
{
public:
using base::test;
};
int main(void)
{
derived d;
// This works, calling derived::test(), which in turn calls base::test()
d.test();
// This does not work, saying 'base' is an inaccessible base of 'derived',
// but I am not binding base::test, I am binding derived::test.
boost::function<void()> fn;
fn = boost::bind(&derived::test, d);
fn();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该using声明没有定义一个函数.它"声明一个名称"(不是函数!),并取消隐藏基本名称.确实,声明本身具有自己的可访问性级别,这就是您首先使用它的原因,但再次强调:using声明不会声明新的成员函数.例如C++ 11 7.3.3/11:
使用声明声明的实体应在上下文中根据其使用声明时的定义使用它.
在你的情况下,"它的定义"仍然存在void base::test(){},这就是派生类已知并被引用的实体&derived::test.你无法从中获得类型的函数指针,void(derived:**)()因为没有这样的函数.
当你说&derived::test,使用&-operator,就像这样工作(5.3.1/3):
一元运算
&符的结果是指向其操作数的指针.操作数应为左值或限定ID.如果操作数是一个合格-ID命名一个非静态成员m一些类的C类型T,结果类型"指针类的成员C类型的T",并且是一个指定prvalueÇ::米.
在我上面的逻辑演绎,&derived::test"名非静态成员test类的base".[感谢@DyP:]在10.2/3中正式化:
对设置的查询
f中C[...]由[...]声明集[...].在声明集中,using声明由它们指定的成员替换
如果你真的想要,你可以提供这样的包装:
class derived : protected base
{
public:
void test() { base::test(); }
};
Run Code Online (Sandbox Code Playgroud)
(奇怪的是,这种解决方案实际上确实隐藏了基函数,这是我们想要的.而不是使用using,我们用一个明确的限定名称来指基函数).
调用函数时,隐式this参数需要转换为基类.该using声明不调整的类型test,从base::*到derived::*.
您可以手动执行此类调整:
static_cast< void (derived::*)() >( &derived::test )
Run Code Online (Sandbox Code Playgroud)
但这同样要求基座可以进入.因此,完整的解决方案是将上述内容封装static_cast在派生类中.否则它应该是一个可访问的基础.
| 归档时间: |
|
| 查看次数: |
352 次 |
| 最近记录: |