2015-09-17 36 views
1

免責聲明:此描述包含大量的Qt特定功能。這不是回答這個問題所必需的,我只是用它來解釋背景。C++:使用mem_fn和bind1st創建一個函數對象

我需要在我的QT應用程序中執行一些繁重的計算。 爲了做到這一點,我想使用QtConcurrent::run(myFunction)這是Qt的異步版本,並創建了一個未來,在某些時候將包含myFunction的結果。

問題是該函數既是成員函數又是複雜的參數。

我知道你可以傳遞一個函數和一個指向QtConcurrent :: run的指針。該函數將在指針上被調用。你甚至可以提供一個參數列表。但似乎這個列表只接受參數,如int,doubleQString

實際問題:

我想這行代碼轉換:

model->nextStep(simulatedResult->last().molecules, dt) 

myFunction() 

這意味着我需要

  1. 綁定該函數指針
  2. 參數綁定到函數

這是到目前爲止我的代碼:

auto memfun=std::mem_fn(&ConcreteModel::nextStep); 
auto memfun_bound_to_model=std::bind1st(memfun,model); 
auto memfun_bound_result=std::bind1st(memfun_bound_to_model,simulatedResult->last().molecules); 
auto memfun_bound_dt=std::bind1st(memfun_bound_result,dt); 

可惜,這是行不通的。 有18個編譯器錯誤,這裏是pastebin:http://pastebin.com/2rBQgFNL

這將是偉大的,如果你能解釋如何正確地做到這一點。 對於答案不是必需的,但更好的情況是QtConcurrent :: run的代碼。

回答

4

只需使用一個lambda expression.

auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); } 

您也可以使用std::bind(見@JonathanWakely的答案),但LAMDA表達式恕我直言,更具有普遍性和強大。另外,請記住,從多個線程讀取和寫入同一內​​存將導致數據競爭(除非使用同步,否則不要將指針/可變數據引用傳遞給QT線程)。

+0

尼斯。這工作和優雅。 – lhk

+0

感謝有關數據競賽的警告。但這是故意的。結果非常大,副本會浪費大量的內存。所有訪問都是同步的(至少我希望如此) – lhk

+0

@lhk似乎合理的是不復制數據。樂意效勞! – Snps

4

您正在嘗試將C++ 98 bind1st與C++ 11 mem_fn混合,這是不可能的。

bind1st需要adaptable binary function這意味着一個定義了某些類型定義,和一個取恰好兩個參數。你不能將它用於需要多於兩個的東西,並且一次保持綁定一個參數。

在C++ 11能夠包裹在沒有那些類型定義功能對象,這要歸功於decltype等新功能,所以「適應性二元函數」是一個概念無用現在,和bind1st是無用的,棄用。

該解決方案僅僅是使用C++ 11功能而不是bind1st,例如, std::bind或lambda表達式。

auto myFunction = std::bind(&ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt); 
相關問題