C ++结构中的回调

时间:2018-10-08 20:26:32

标签: c++ callback function-pointers std-function

我一直试图在c ++中实现回调函数。在一个类中,我有一个结构,许多方法以及一个使用其他方法之一作为参数创建该结构实例的方法。

该结构还有许多其他变量,但此处显示了一个示例:

class MYCLASS
{
public:
    MYCLASS();

    struct TEST{
        std::function<int(int)> foo;
    };

    int plus(int x){
        return x + 1;
    }

    int minus(int x){
        return x - 1;
    }

    void sim(){
        TEST T;             // make an instance of TEST
        T.foo = plus(5);    // assign TEST.foo a function (plus or minus)  
        T.foo();            // call the method we assigned
    }
};

sim方法中,我想创建一个test的实例,并根据某些标准为其指定plusminus。我尝试为实例T提供plus函数并随后调用它的两行都是错误的。

2 个答案:

答案 0 :(得分:1)

如果您希望将呼叫延迟到T.foo,则可以使用如下所示的lambda:

    T.foo = [this](int x) { return plus(x); };
    T.foo(5);

答案 1 :(得分:1)

选项-1

如果成员函数plus()minus()足够简单(如您所示),则可以将它们作为结构TEST中的lambda函数。 由于无需捕获的lambdas 可以存储在键入的函数指针中,因此以下操作将满足您的需求。 See live demo

#include <iostream>
class MYCLASS
{
    int m_var = 5; // just for demonstration
public:
    MYCLASS() = default;
    struct TEST
    {
        using fPtrType = int(*)(int);   // function pointer type
        const fPtrType foo1 = [](int x) { return x + 1; };  // plus function
        const fPtrType foo2 = [](int x) { return x - 1; };  // minus function
    };

    void sim()
    {
        TEST T;
        std::cout << "Answer from int PLUS(int): " << T.foo1(m_var) << std::endl;
        std::cout << "Answer from int MINUS(int): " << T.foo2(m_var) << std::endl;
    }
};

选项-2

如果以上内容对您的代码有很大影响,请再次对成员函数使用类型化的函数指针,并执行以下操作;这样可以避免不必要地复制(通过捕获类实例到lambda)和模板实例化以及其他 performance issues {{ 3}}。

with std::function

#include <iostream>    
class MYCLASS
{
    using fPtrType = int(MYCLASS::*)(int); // class member function pointer type
public:
    MYCLASS() = default;
    struct TEST { fPtrType foo = nullptr; };

    int plus(int x) { return x + 1; }
    int minus(int x) { return x - 1; }

    void sim()
    {
        TEST T;
        T.foo = &MYCLASS::plus; // now you can
        std::cout << "Answer from int PLUS(int): " << (this->*T.MYCLASS::TEST::foo)(5) << std::endl;
                                                     //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ syntax would be a bit ugly
        // later same ptr variable for minus()
        T.foo = &MYCLASS::minus;
        int answer = (this->*T.MYCLASS::TEST::foo)(5);
        std::cout << "Answer from int MINUS(int): " << answer << std::endl;
    }
};

int main()
{
    MYCLASS obj;
    obj.sim();
    return 0;
}

输出:

Answer from int PLUS(int): 6
Answer from int MINUS(int): 4