在C ++中模仿特殊的JavaScript回调

时间:2014-01-22 09:29:56

标签: javascript c++ callback

我在使用C ++中的这种类型的回调实现方面遇到了麻烦。在下面的代码中,我想将回调存储到“OnRenderingComplete”中。但是,我无法记住“adOnRenderingComplete”的“ad”变量和“回调”参数。 这是如何在C ++中实现的?

var adOnRenderingComplete = function(ad, callback) {

};

var setAdPlaybackCallbacks = function(ad, callback) {

    OnRenderingComplete = function() { adOnRenderingComplete.call(this, ad, callback); };
};

在JavaScript中,似乎这是可能的,因为可以存储存储“ad”和“callback”参数的嵌入式函数......但我不确定如何在C ++中完成。我最终想调用OnRenderingComplete(),“记住”参数“ad”和“callback”。

我很难过。我似乎无法弄清楚这一点。我能想到的唯一关闭是在函数中定义一个类并将该类的函数传递给OnRenderingComplete。但即便如此,下面的内容也是错误的,不会编译。

void testCall(void (*callback)())
{
    callback();
}

void test1()
{
    class blah
    {
    public:
        int a;
        int b;
        void c()
        {
            cout << "a * b = " << a*b << endl;
        };
    };

    blah ex;
    ex.a = 5;
    ex.b = 3;

    void(*OnRenderingComplete)() = ex.c;
    testCall(OnRenderingComplete);    // I would like to have this print the value of a*b
}

基本上,我试图在回调变量“OnRenderingComplete”中捕获“ex.c”。但是,与此同时,我想捕获ex.a和ex.b的值,以便在“记住”“a”和“b”的数据时可以调用ex.c.在调用“testCall(OnRenderingComplete)”之后,我希望testCall()顶部的函数能够打印a * b的值。

1 个答案:

答案 0 :(得分:2)

多种解决方案(点击标题即可获得实例):

<强> C++11

#include <functional>

struct MyClass
{
    typedef std::function<void (int, bool)> CallbackType;
    typedef std::function<void (int, float, bool)> AnotherCallbackType;
    CallbackType callback;

    void setCallback(AnotherCallbackType c, float param)
    {
        callback = [&](int a, bool b) { c(a, param, b); };
        // Calling the callback:
        callback(42, false);
        // With lambdas, it is almost like in Javascript,
        // you can embed all parameters you want. ex:
        std::function<void()> func = [&](){ c(2, param, true); };
        func(); // will call c(2, param, true);
    }
};

<强> C++03, with Boost

#include <boost/function.hpp>
#include <boost/bind.hpp>

struct MyClass
{
    typedef boost::function<void (int, bool)> CallbackType;
    typedef boost::function<void (int, float, bool)> AnotherCallbackType;
    CallbackType callback;

    void setCallback(AnotherCallbackType c, float param)
    {
        callback = boost::bind(c, _1, param, _2);
        // Calling the callback:
        callback(42, false);
        // This will call: c(42, param, false)
        // The 'param' float parameter has been retained.
        // It is possible to retain all parameters when binding, ex:
        boost::function<void()> func = boost::bind(c, 2, param, true);
        func(); // will call c(2, param, true);
    }
};

<强> C++03, without Boost

struct MyClass
{
    typedef void (MyClass::* CallbackType)(int, float);
    CallbackType callback;

    void onRenderCallback(int param1, float param2) {}
    void setCallback(CallbackType c)
    {
        callback = c;
        // Calling the callback:
        (this->*callback)(42, 3.14f);
        // Note that it is possible to embed the parameters
        // but that will need to create a class, basically it means you will reimplement Boost.Bind...
    }
};

现在,回到你的代码:

void(*OnRenderingComplete)() = ex.c;

对于指向函数的指针,我认真建议你使用typedef:

typedef void (*OnRenderingCompleteType)();
OnRenderingCompleteType callback = ...;

然后,ex.c具有以下类型:void (blah::*)()。注意blah::*,这是因为这是一个指向成员的函数,不是指向函数的指针(成员函数是特殊函数)。这就是分配无法编译的原因。