class animal {
protected:
animal() {}
void eat(int x) {}
};
class human
: private animal
{
public:
typedef animal base_type;
using base_type::eat;
};
class stomach {
public:
stomach(std::function<void(int)> feed) {}
};
class lady
: public human
{
public:
typedef lady this_type;
typedef human base_type;
lady()
: base_type()
, m_Stomach(std::bind(&base_type::eat, this, std::placeholders::_1))
{
}
private:
stomach m_Stomach;
};
如果客户端代码写下:
lady gaga;
编译器抱怨std::bind(&base_type::eat, ...)
错误C2064:term不评估为带有2个参数的函数。
我发现如果班主任修改为:
class lady
: public human
{
public:
typedef lady this_type;
typedef human base_type;
lady()
: base_type()
, m_Stomach(std::bind(&this_type::help_eat, this, std::placeholders::_1))
{
}
private:
void help_eat(int x)
{
base_type::eat(x);
}
stomach m_Stomach;
};
使用帮助功能,编译器将std::bind
好。但代码重复。
我还发现如果将std::bind
更改为lambda m_Stomach([&](int x){ base_type::eat(x); })
,也可以编译。
我的问题是,在这种情况下使用std::bind
是否有更好的方法?如果没有,我可能会考虑lambda。
答案 0 :(得分:2)
您的问题是animal
是私有基类human
,因此传递(并存储)this
(类型为{{1} }})不能用于从lady*
调用方法。您可以修复它,使其成为公共基础或向animal
添加方法:
human
以后绑定:
animal* animal_ptr() { return this; }
答案 1 :(得分:0)
动物是人类的私人基类,虽然使用声明使得函数可用,但它不会改变函数的签名void (animal::*)(int)
。
从7.3.3使用声明
为了重载解析,其功能是 由using声明引入派生类将被处理 好像他们是派生类的成员。特别是 隐式此参数应被视为指向它的指针 派生类而不是基类。 这对此没有影响 函数的类型,以及所有其他方面的函数 仍然是基类的成员。
因此,绑定(指代函数类型)会导致错误‘animal’ is an inaccessible base of ‘lady’
(g ++)。
您可以使用lambda m_Stomach([this](int x) { this->eat(x); })
修复它,
用void eat(int x) { base_type::eat(x); }
代替人类的使用声明,或者按照你的方式去做。