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

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

问题描述

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

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 (int argc, const char* argv[])
{
    aClass a();

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

    return 0;
}

如何使用aaClass::test作为function1的参数?我坚持这样做.

How can I use the a's aClass::test as an argument to function1? I'm stuck in doing this.

我想访问课程的成员.

推荐答案

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

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, 0);
    foo object;
    somefunction(&forwarder, &object);
}

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

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