难以传递 class 成员函数的函数指针

Difficulty in passing function pointer of a class member function

在尝试在我自己的上下文中实施建议的答案 here 时,我 运行 遇到了编译错误。

考虑代码:

#include <iostream>

class SIMPLE {
public:
    SIMPLE() { for (int i = 0; i < 5; i++) val[i] = 5; };
    int retval(int index) { return val[index]; }
private:
    int val[5];
};

void print_array_of_length5(int (*fnptr)(int index)){
    for (int i = 0; i < 5; i++)
        printf("%d ", fnptr(i));
}

int global_array[5] = { 0, 1, 2, 3, 4 };
int global_function(int index){
    return global_array[index];
}

int main(){
    print_array_of_length5(&global_function);//Works fine.
    int (SIMPLE::*p)(int) = &SIMPLE::retval;//Following method suggested in the answer above
    class SIMPLE smpl;
    print_array_of_length5(smpl.*p);//Compile error: a pointer to a bound function may only be used to call the function
}

该函数在提供全局函数地址时工作。当通过 smpl.*p 类似于建议的方法时,它不起作用。应该如何解决这个错误?

您需要 print_array_of_length5 的另一个重载以传递成员函数指针:

template<typename T>
void print_array_of_length5(int (T::*fnptr)(int index), T& obj)
{
    for(int i = 0; i < 5; ++i)
    {
        printf("%d ", (obj.*fnptr)(i));
    }
}

int main()
{
    SIMPLE smpl;
    print_array_of_length5(&SIMPLE::retval, smpl);
}

您不能将非静态成员函数指针作为常规函数指针传递。成员函数可以访问 this 指针,它们获取该指针的方式是通过一个不可见的隐式函数参数。您需要将调用函数的对象和函数本身绑定在一起,而函数指针根本无法做到这一点。

我们可以做的是 print_array_of_length5 一个函数模板,并允许它接受任何类型的可调用对象。那会给你这样的东西:

template <typename Function>
void print_array_of_length5(Function func){
    for (int i = 0; i < 5; i++)
        printf("%d ", func(i));
}

要用非静态成员函数调用它,可以使用lambda表达式,或者std::bind(),像这样:

SIMPLE smpl;
print_array_of_length5([&smpl](int foo){ return smpl.retval(foo); });
using namespace std::placeholders;
SIMPLE smpl;
auto func = std::bind(&SIMPLE::retval, &smpl, _1);
print_array_of_length5(func);