2016-03-13 70 views
0

我在傳遞類指針作爲lambdas回調中的參數時出現問題。Lambdas和傳遞一個指針類作爲參數

引擎收錄:http://pastebin.com/SqXHtGDt

我如何定義回調:

typedef void (*cb_prescription)(Prescription * prescription); 

我如何使用回調:

void loop_prescriptions (cb_prescription callback, bool add = true) 
{ 
    for (int i = 1; i <= prescriptions->noOfElements(); i++) { 
     Prescription * prescription = (Prescription *) prescriptions->removeNo(i); 
     if (add) { 
      prescriptions->add(prescription); 
     } 
     callback(prescription); 
    } 
} 

我知道一切正常,除了參數指針部分。

loop_prescriptions ([&] (Prescription * paper) { paper->something(); }); 

我得到的錯誤:

錯誤:無法轉換 'list_prescriptions_by_doctor()::' 到 'cb_prescription {又名無效()(處方*)}' 的說法 '1'到'void loop_prescriptions(cb_prescription,bool)' }); *

有誰知道我如何使用參數不正確? 我試圖添加指針的參考* &,只是刪除指針,但List類(是的,我必須使用這個)返回一個類指針,所以我不能簡單地使用副本。

感謝您的幫助!

UPDATE 我已經根據答案更新了我的pastebin,它提供了一個工作解決方案。 http://pastebin.com/7yTPGEQx

+2

您無法將有狀態的lambda(可捕獲任何內容)轉換爲函數指針。這就是錯誤所說的。要麼不使用(非全局)狀態,要麼修改'loop_prescriptions'簽名。 – Yakk

+0

所以我需要事先將所需的任何參數傳遞給lambda範圍? – andersfylling

+0

不,如果您打算使用回調類型和所有使用該回調類型的類,則必須使用上下文無關的lambda表達式。不錯,如果你需要這個上下文,那麼你需要相應地改變回調類型。 – user3159253

回答

1

當你傳遞一個lambda(或換句話說,任何隨機類)時,你的函數只接受函數指針。由於類不是函數指針,最有可能願意接受仿函數(如一切這就好比功能)

我想你可以在2種不同的方式更改代碼:

// Using a std::function object; which wraps both function pointers and classes with() operator 
using cb_prescription = std::function<void(Prescription*)>; 

template<typename cb_prescription> 
void loop_prescriptions (cb_prescription &&callback, bool add = true) 

第一個變體是我更喜歡的變體,因爲這是非常通用的,不幸的是它帶來了包裝回調的性能開銷。除非你在關鍵性能代碼中,否則我會使用這個。

第二個變體通過模板工作,所以無論你通過哪裏,可以用()運算符和匹配參數調用都可以。但是,它要求此代碼適用於所有呼叫者。由於模板,函數ptr,lambda的確切類型是已知的,所以您不會從std :: function中獲得開銷。

+0

我究竟會如何使用第一個? https://codeshare.io/o6Ryj – andersfylling

+1

嘗試添加'#include '並使用正確的lambda語法'[](){}' PS:不要使用auto_ptr,它已棄用,請使用'std :: unique_ptr相反。 – JVApen

+0

任何想法如何我可以修改它,使其使用不同的類名稱? 使用Callback = std :: function void>; – andersfylling