2017-01-09 54 views
1

我使用的是函數的引用(不是我的,從庫,我不控制),用類似這樣的簽名:獲取對拉姆達的捕捉值

template<typename T, typename F> 
void do_async(T const&, F); // the second parameter is a callable 

,通常像這樣使用

do_async(obj, [this](){ ... }); 

我寫了一個類似的功能總是使用相同的回調拉姆達:

template<typename T> 
void do_async_wrapper(T obj) { 
    do_async(obj, [this](){ ... }); 
} 

我的問題造成的FR om因爲obj作爲參考傳遞,所以必須保持活動狀態,直到調用回調。我的功能應該考慮到這一點,所以調用者不必擔心對象的生命週期。這就是爲什麼它按價值接受。
我願做這樣的事情,以保持它活着:

template<typename T> 
void do_async_wrapper(T obj) { 
    do_async(obj, [this, obj{std::move(obj)}](){ ... }); 
} 

顯然,這不會(總是)工作的,是因爲參考指向函數本地一個不存在了,而保持活力的是它的(移動)副本。

有什麼建議嗎?

+0

什麼'do_async'與參數做什麼?你確定它不在內部複製嗎? – TartanLlama

+0

@TartanLlama是的。庫文檔指定確保對象保持活動狀態是調用者的責任。 – baruch

+0

你能鏈接到文檔嗎?一個選項是'std :: shared_ptr'。 – TartanLlama

回答

2

由於函子是按值取值的,因此不能直接在函數中存儲對象並傳遞它的引用。 您可以變通,通過使用智能指針爲shared_ptr

template<typename T> 
void do_async_wrapper(T obj) { 
    auto ptr = std::make_shared<T>(std::move(obj)); 
    do_async(*ptr, [this, ptr](){ /*...*/ }); 
} 
+0

我被'make_unique'而不是'make_shared'誘惑,因爲'do_async'不應該*拷貝* lambda。但是這需要額外的一行才能使其工作('auto&obj_ref = * ptr;')。 – Yakk

+0

@Yakk我使用make_unique進行類似的解決方案。我不需要你展示的那一行。它的目的是什麼? – baruch

+0

@baruch:在'* ptr'和'[ptr = std :: move(ptr)]'之間存在2個問題,未指定的順序,'do_async'中的'F'的副本(這使得2個實例'T'不同)。 – Jarod42