簡體   English   中英

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

[英]Mimicking Special JavaScript Callback in C++

我在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的值。

幾個解決方案(點擊標題為實例):

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,帶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,沒有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::* ,這是因為這是一個指向成員的函數, 而不是指向函數的指針(成員函數是特殊函數)。 這就是為什么賦值不能編譯的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM