typedef void (*funcPtrType)(); // function pointer type
map<char,funcPtrType>eventGroups;
void addSharedEvent(char groupIndex,void (*receiverFunc)() ){
if(groupIndex==0)
return;
eventGroups[groupIndex]=receiverFunc;
}
如果添加内联函数,它就能工作,但如果使用非内联类成员函数,它就不能工作,如下面所示。。。
void MainWin::uiValsUpdated()
{
}
void MainWin::test()
{
//invalid
wSync.addSharedEvent(4,&uiValsUpdated);
}
如何制作访问各种类型类中函数的通用指针? 或者,也可以定义类类型,但仍然是以通用的方式,例如QT,信号和插槽。
typedef void (*funcPtrType)(); // function pointer type
避免像这样混淆指针类型。
它在添加内联函数时起作用,但在使用非内联类成员时不起作用
它与内联与非内联没有关系,而与函数指针不能指向非静态成员函数这一事实有关。
如何制作访问各种类型类中函数的通用指针?
函数指针可以指向除非静态成员函数以外的函数,只要原型匹配即可。 要调用这样的函数,不需要任何类实例。 示例:
void free_function() {}
auto fun_ptr = &free_function;
fun_ptr();
成员函数的指针可以指向具有匹配原型的特定类的非静态成员函数。 为了调用这样的指向函数,必须有类的实例。 示例:
struct foo {
void member_function(){}
};
auto mem_fun_ptr = &foo::member_function;
foo f;
f.*mem_fun_ptr();
函数对象可以用作包装器,它可以调用任何类型的函数。 如果要调用成员函数,则可以将所需的实例存储为成员。 lambda是创建这样函数对象的简写。 示例:
auto lambda_free = [] {
free_function();
}
auto lambda_member = [f] {
f.member_function();
}
lambda_free();
lambda_member();
类型擦除技术可以用来隐藏各种函数对象的类型,因为它们可以以完全相同的方式调用。 Standard附带了一个用于此目的的模板:std::function
。 示例:
std::function<void()> fun_wrapper;
fun_wrapper = lambda_free;
fun_wrapper = lambda_member;
fun_wrapper = fun_ptr;
//fun_wrapper = mem_fun_ptr; // nope; there is no instance of foo
指向自由函数的指针与指向成员函数的指针有很大不同。 不仅语法不同,成员函数指针还需要一个这个
第一个参数--它们应该对其进行操作的类的实例。 如果您打算处理原始(成员)函数指针,则不能使用相同的映射
来存储两者。
一种解决方案是某种类型的类型擦除; 您可以在映射
中存储std::function
对象:
map<char, std::function<void()>>eventGroups;
void addSharedEvent(char groupIndex, const std::function<void()>& callback){ ... }
您可以通过普通函数指针构造参数,如果是成员函数,则可以使用std::bind
或lambda。