提问者:小点点

类通用函数指针


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,信号和插槽。


共2个答案

匿名用户

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。