簡體   English   中英

將Lambda轉換為函數指針typedef

[英]Converting a lambda to function pointer typedef

我有一個第三方API,該API具有將函數指針作為參數(示例類型)的函數:

// defined in "Api.h"
typedef int (*Callback) (int x); 

unsigned char ApiCall(int p, Callback cb);


int ApiCall(int p, Callback cb) {
   return cb(p);
}

我正在嘗試使用類實例方法與此API進行交互; 這是一個示例類:

class ApiWrapper {
    public:
        int ApiCallback(int x) { return this->factor_ * x; }

        static int WorkingApiCallback(int x) { return 3 * x; }

        ApiWrapper(int f) { this->factor_ = f; }

    private:
        int factor_;
} 

並測試一個主要功能:

#include <iostream>
#include <functional>

int main() {
    ApiWrapper a(2);

    using std::placeholders::_1;
    std::function<int(int)> lambda = std::bind( &ApiWrapper::ApiCallback, a, _1 );

    std::cout << "Class: "  << a.ApiCallback(21) << std::endl;
    std::cout << "Lambda: " << lambda(21) << std::endl;
    std::cout << "Static ApiCall:" << ApiCall(21, ApiWrapper::WorkingApiCallback) << std::endl;

    // NOT WORKING 
    std::cout << "Static ApiCall:" << ApiCall(21, lambda) << std::endl;
    std::cout << "Static ApiCall:" << ApiCall(21, this.ApiCallback) << std::endl;    

    return 0;
}

有沒有一種方法可以不使用static成員來實現? 因為每次第三方庫調用回調時,我都需要關聯/使用狀態。

謝謝!

您將必須以某種方式將非成員與函數指針相關聯,因為它不需要任何類型的上下文參數。 您將在某個時候擁有一個非成員函數,沒有辦法解決。 而且該函數不能是捕獲的lambda。

一種選擇是擁有一個(可能是線程局部的)全局指針來保存實例。

即你做:

myType * glbInst;
..void someFunc()
{
 myType myInst;
  glbInst = &myInst;
  apiCall([] (int)  glbInst->member(x); });
}

另一種選擇是使用libffi的閉包系統在運行時創建一個函數,並將實例作為已保存數據的一部分。 我經常使用此模式,但在此處粘貼有點復雜。

有沒有一種方法可以不使用靜態成員來實現?

有一個棘手的解決方案。

  1. 定義一個非成員函數。
  2. 存儲一個指向非成員函數可以訪問的對象的指針。
  3. 從非成員函數中調用對象的成員函數。

ApiWrapper* objectForCallback = NULL; 

int  NonMemberFunction(int x)
{
   assert(objectForCallback != NULL);
   return objectForCallback->ApiCallback(x);
}

以及上面的設置可以正常工作:

ApiWrapper a(2);
objectForCallback = &a;

現在您可以使用:

std::cout << "Static ApiCall:" << ApiCall(21, NonMemberFunction) << std::endl;    

暫無
暫無

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

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