我想将class X
的C函数指针绑定到class Y
的另一个成员函数。
他们的实现看起来像这样
//The class w/c has the C-function pointer
class XString
{
public:
...
private:
void (*eventOnChange)();
friend class swc::swcText;
};
//The class w/c I want to assign/bind the XString::eventOnChange;
class swcText
{
public:
swcText()
{
//how can I do this
text.eventOnChange = &swcText::computeTextSize;
}
...
XString text;
private:
void computeTextSize();
};
我想实现text.evenOnChange = this->computeTextSize
但我得到了一个汇编
error ..\swctext.cpp|25|error: cannot convert 'void (swc::swcText::*)()' to 'void (*)()' in assignment|
我知道我可以使用std::function<void()> eventOnChange
执行此操作并分配lambda函数,但如何在C风格的函数指针中执行此操作?
答案 0 :(得分:3)
当您调用非static
成员函数时,您始终将对象的引用传递给函数,即this
指向的实体。声明为void(*)()
的函数不接受任何参数,因此与成员函数指针不兼容:无法分配它们。你需要以某种方式获得额外的对象。当然,最简单的方法是将std::function<void()>
和std::bind()
函数用于对象(不需要使用lambdas):
std:function<void()> f;
f = std::bind(&Y::computeTextSize, this);
如果你坚持不想使用类似的东西,你可以建立类似于std::function<void()>
和std::bind()
的功能,这些功能非常有限:
class function
{
void* object;
void (*fun)(void*);
public:
function(): object(), fun() {}
function(void* o, void(*f)(void*)): object(o), fun(f) {}
void operator()() const { if (object) (this->fun)(object); }
};
template <typename T, void (T::*member)()>
void call(void* object) {
(static_cast<T*>(object)->*member)();
}
template <typename T, void (T::*member)()>
function bind(T* object) {
return function(object, &call<T, member>);
}
您可以使用上述功能,例如
text.eventOnChange = bind<swcText, &swcText::computeTextSize>(this);
但请注意,std::function<...>
和std::bind()
往往会带来一些额外的技巧,并且可以更有效地使用,尤其是在将具有内联调用操作符的函数对象传递给它们时(除了很多更灵活。)