2017-04-18 39 views
2

所以我想通過在C++中編寫一個小線程池來挑戰自己,並且我試圖模仿std :: thread使用的簡單易用的方法,您可以創建一個線程,並作爲參數發送一個函數和該函數的參數,相比之下像pthreads這迫使你有一個void *作爲函數的唯一indata。C++存儲函數和參數列表供以後使用

到目前爲止,我已經能夠使用模板和參數包來創建一個函數,它可以接受另一個函數和參數並執行它,但是我找不到一種方法來存儲它們以便我可以執行它們在稍後的時間(當線程池中有空閒線程時)。我已經嘗試使用std ::函數一起使用std :: tuple和std :: bind,但是因爲我不知道到底是什麼類型,我無法找到一種方法來存儲函數和參數這樣我就可以稍後在我的代碼的另一部分中使用它們,因爲那時我不再知道所有類型的類型。下面是我一直在搞的一些代碼,可能有助於說明我的意思。

template<typename Function, typename... Arguments> 
void TestFunction(Function func, Arguments... parameters) 
{ 

std::function<std::result_of<Function(Arguments...)>::type(Arguments...)>* tempFunc; 
tempFunc = new std::function<std::result_of<Function(Arguments...)>::type(Arguments...)>(func); 
void* funcPtr = tempFunc; 
std::tuple<Arguments...>* tempTuple; 
tempTuple = new std::tuple<Arguments...>(parameters...); 
void* tuplePtr = tempTuple; 

//func(parameters...); 
(Arguments...)>*)funcPtr, *(std::tuple<Arguments...>*)tuplePtr); 

auto bindTest = std::bind(func, parameters...); 
bindTest(); 
void* bindPtr = &bindTest; 

} 

int main() 
{ 
TestFunction(std::printf, "%d, %d, %d\n", 3, 2, 1); 

getchar(); 
return 0; 
} 

這可能是它不可能做我想做的事,而在這種情況下,我想我就必須切換到更像是並行線程的方法。但如果有人知道一個工作,我會很感激。

+0

你試過lambdas嗎?它可以存儲函數調用和參數沒有任何問題。 –

+0

@MichaelNastenko我已經看過他們,但如何將它們存儲在一般意義上的問題也適用於它們 – Gamewolf3000

+0

您可以在lambda中使用'std :: packaged_task',它將負責存儲參數並返回值。 –

回答

2

關鍵是您可以將std :: bind的返回類型存儲在std :: function中。因爲std :: bind返回一個可調用的對象。然後,您應該能夠存儲std :: function實例,具體取決於您想要如何處理返回類型。

template<typename Function, typename... Arguments> 
void TestFunction(Function func, Arguments... parameters) 
{ 
    using Ret = typename std::result_of<Function>::type; 
    std::function<Ret()> val{std::bind(func, parameters...)}; 
} 

如果您在第一次接收函數時執行此操作,則不再需要考慮參數類型以及返回類型。如何處理返回類型取決於存儲函數的用例。一個簡單的方法是要求Function是一個無效函數,如果沒有辦法將值傳遞給API的使用者,這可能是有意義的。

+0

這聽起來像一個體面的解決方案,我希望能夠有返回值,但我可以用你的方式,只是有不同的方式來存儲標準類型(如int,float和char),不讓用戶發送具有自定義類型返回值的函數。那麼我猜測那就沒有辦法存儲一個完整的通用函數了? – Gamewolf3000

+0

@ Gamewolf3000你打算如何將返回值傳遞給TestFunction的消費者?如果你打算直接從測試函數中返回類似值的未來,你可以將函數轉換爲void callable。或者,如果要在存儲函數的類上使用另一個函數,則可能必須在返回類型上對其進行參數化。 – user1937198

+0

我原本打算從api的函數中返回一種智能指針,從中可以檢索有關任務狀態(等待,完成等)的信息,還有一個指向返回數據的void指針。但是我越想越分崩離析,因爲即使我可以推廣它,那麼如何處理非動態分配的回報(誰負責它)也是一個問題。所以相反,如果你不能得到返回值並且用戶需要解決這個問題,那麼它可能會更好,但是如果有一種方法來獲取任何類型的函數 – Gamewolf3000

相關問題