如何在需要自由函数的地方传递成员函数? [英] How can I pass a member function where a free function is expected?

查看:25
本文介绍了如何在需要自由函数的地方传递成员函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题如下:考虑这段代码:

The question is the following: consider this piece of code:

#include <iostream>


class aClass
{
public:
    void aTest(int a, int b)
    {
        printf("%d + %d = %d", a, b, a + b);
    }
};

void function1(void (*function)(int, int))
{
    function(1, 1);
}

void test(int a,int b)
{
    printf("%d - %d = %d", a , b , a - b);
}

int main()
{
    aClass a;

    function1(&test);
    function1(&aClass::aTest); // <-- How should I point to a's aClass::test function?
}

如何使用aaClass::test 作为function1 的参数?我想访问班级的成员.

How can I use the a's aClass::test as an argument to function1? I would like to access a member of the class.

推荐答案

使用函数指针没有任何问题.但是,指向非静态成员函数的指针与普通函数指针不同:需要在作为隐式参数传递给函数的对象上调用成员函数.上面你的成员函数的签名是,因此

There isn't anything wrong with using function pointers. However, pointers to non-static member functions are not like normal function pointers: member functions need to be called on an object which is passed as an implicit argument to the function. The signature of your member function above is, thus

void (aClass::*)(int, int)

而不是您尝试使用的类型

rather than the type you try to use

void (*)(int, int)

一种方法可以包括使成员函数 static 在这种情况下它不需要调用任何对象,并且您可以将它与 void (*)(int, int).

One approach could consist in making the member function static in which case it doesn't require any object to be called on and you can use it with the type void (*)(int, int).

如果您需要访问类的任何非静态成员并且您需要坚持使用函数指针,例如,因为该函数是 C 接口的一部分,您最好的选择是始终将 void* 传递给您的函数,并使用函数指针并通过转发函数调用您的成员,该函数从 void* 获取对象,然后调用成员函数.

If you need to access any non-static member of your class and you need to stick with function pointers, e.g., because the function is part of a C interface, your best option is to always pass a void* to your function taking function pointers and call your member through a forwarding function which obtains an object from the void* and then calls the member function.

在适当的 C++ 接口中,您可能想看看让您的函数采用函数对象的模板化参数以使用任意类类型.如果不希望使用模板化接口,您应该使用类似 std::function<void(int, int)>:您可以为这些创建一个合适的可调用函数对象,例如,使用 std::bind().

In a proper C++ interface you might want to have a look at having your function take templated argument for function objects to use arbitrary class types. If using a templated interface is undesirable you should use something like std::function<void(int, int)>: you can create a suitably callable function object for these, e.g., using std::bind().

使用类类型的模板参数或合适的 std::function<...> 的类型安全方法比使用 void* 更可取接口,因为它们消除了由于转换为错误类型而导致错误的可能性.

The type-safe approaches using a template argument for the class type or a suitable std::function<...> are preferable than using a void* interface as they remove the potential for errors due to a cast to the wrong type.

为了阐明如何使用函数指针来调用成员函数,这里有一个例子:

To clarify how to use a function pointer to call a member function, here is an example:

// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
    fptr(context, 17, 42);
}

void non_member(void*, int i0, int i1) {
    std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}

struct foo {
    void member(int i0, int i1) {
        std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
    }
};

void forwarder(void* context, int i0, int i1) {
    static_cast<foo*>(context)->member(i0, i1);
}

int main() {
    somefunction(&non_member, nullptr);
    foo object;
    somefunction(&forwarder, &object);
}

这篇关于如何在需要自由函数的地方传递成员函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆