简体   繁体   English

指向类成员函数的函数指针

[英]Function pointer to class member function

I want to make function which has function pointer as a parameter. 我想制作以函数指针作为参数的函数。

#include <iostream>
using namespace std;

class test{

public:
    test(){};

    double tt(double input){
        return input;
    };

};

double fptr_test(double (*fptr)(double), double input){
    return fptr(input);
}


int main(){

    test t;
    cout << t.tt(3) << endl;
    cout << fptr_test(t.tt, 3) << endl;  // This line doesn't work
    cout << fptr_test(&test::tt, 3) << endl;  // This line can't compile

    return 1;
}

But it doesn't work. 但这是行不通的。 How could I pass class member function as a parameter? 如何传递类成员函数作为参数?

Can I call the member function without instantiation? 我可以不实例化地调用成员函数吗?

If you want to pass a pointer to a member-function, you need to use a member-function-pointer, not a pointer for generic free functions and an object to invoke it on. 如果要传递指向成员函数的指针,则需要使用成员函数指针,而不是泛型自由函数的指针以及用于对其进行调用的对象。

Neither is optional. 两者都不是可选的。

double fptr_test(test& t, double (test::*fptr)(double), double input){
    return t.*fptr(input);
}

// call like this:
fptr_test(&test::tt, 3); // Your second try

A function pointer and a member function pointer have incompatible types. 函数指针和成员函数指针具有不兼容的类型。 For example, the type of &test::tt is 例如, &test::tt的类型是

double (test::*)(double)

rather than 而不是

double (*)(double)

The reason for this difference is that a [non- static ] member function has a hidden parameter: the pointer to the object the member function is applied, too, ie, this . 造成这种差异的原因是,[非static ]成员函数具有隐藏参数:成员函数也被应用到对象的指针,即this The way to a normal function pointer out of a member function is to delegate via a function which supplies the this pointer and, thus, takes an extra argument. 从成员函数中获取普通函数指针的方法是通过提供this指针的函数进行委托,因此需要一个额外的参数。

In C++ it is much more useful to not take function pointers as arguments to functions which can be customized by a function but rather to take a function object . 在C ++中, 不要将函数指针用作可以由函数自定义的函数的参数,而是采用函数对象,这将更为有用。 This approach comes in two flavors: 这种方法有两种口味:

  1. The fast approach is to make the function object type a template argument and to just pass whatever function object you got directly. 快速的方法是使函数对象类型成为模板参数,并直接传递您直接获得的任何函数对象。 For example, you fptr_test() would look like this: 例如,您的fptr_test()如下所示:

     template <typename Fun> double fptr_test(Fun fun, double input) { return fun(input); } 

    The implicit concept used is a function callable with a double argument which yields are result convertible to double . 所使用的隐式概念是带有double参数的可调用函数,其yield可以转换为double结果。

  2. Especially when the functions being called need to be compiled separately, using a template for each kind of function object isn't viable. 尤其是当需要分别编译被调用的函数时,对于每种函数对象使用模板都是不可行的。 In that case it is much more reasonable to use a type-erased representation, ie, std::function<...> , eg: 在这种情况下,使用类型擦除的表示形式(即std::function<...>更为合理,例如:

     double fptr_test(std::function<double(double)> fun, double input) { return fun(input); } 

In both cases the function object takes just one argument while your member function takes two: the object to call the function on and the double argument. 在这两种情况下,函数对象仅接受一个参数,而成员函数则接受两个参数:调用该函数的对象和double参数。 You'd std::bind(...) the first argument to an object and pass the resulting object to fptr_test() : 您将std::bind(...)作为对象的第一个参数,并将生成的对象传递给fptr_test()

  test object;
  std::cout << fptr_test(std:bind(&test::tt, &object, std::placeholders::_1), 3) << '\n';
  std::cout << fptr_test([&](double input){ return object.tt(input); }, 3) << '\n';

The code uses two separate approaches to bind the object: the first uses std::bind() while the second uses a lambda function. 该代码使用两种单独的方法来绑定对象:第一种使用std::bind()而第二种使用lambda函数。 Both of these calls should work with both of the implementation of fptr_test() provided. 这两个调用都应与所提供的fptr_test()两种实现fptr_test()

What you probably want is this: 您可能想要的是:

#include <iostream>
#include <functional>
using namespace std;

class test{

public:
    test(){};

    double tt(double input){
        return input;
    };

};

double fptr_test( std::function<double(double)> func, double input){
    return func(input);
}


int main(){
    using namespace std::placeholders;

    test t;
    cout << t.tt(3) << endl;
    cout << fptr_test( std::bind( &test::tt, t, _1 ), 3) << endl;

    return 0;
}

Btw - when your program finishes correctly you suppose to return 0 from main() 顺便说一句-当程序正确完成时,您假设要从main()返回0

Here is a code after modification. 这是修改后的代码。

#include <iostream>
using namespace std;

class test{

public:
    test(){};

    double tt(double input){
        return input;
    };

};

double fptr_test(test* t, double (test::*fptr)(double), double input){
    return (t->*fptr)(input);
}

int main(){

    test t;
    cout << t.tt(3) << endl;
    cout << fptr_test(&t, &test::tt, 3) << endl;

    return 1;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM