2017-03-20 42 views
0

我正在研究一個將執行某種科學計算的lib。 它旨在與GUI一起使用,因此計算是異步執行的,並且GUI(或任何將任務排入lib)將在先前指定的std::function上收到回調。 這些回調應總是收到一個小的狀態響應對象,即使用右值引用進行異步回調

struct StatusResponse { 
    StatusResponse(int respC, std::string respS): responseCode(respC), 
    responseString(std::move(respS)) {}; 
    int responseCode; 
    std::string responseString; 
}; 

這些回調是發射後不管,他們不返回任何東西(無效),並沒有必要等待被執行的另一個動作回調。 因此,StatusResponse對象也是臨時的。 現在看起來好像有很多種方法。 我的第一個想法是定義回調函數如下

template<typename T0> 
using Action = std::function<void(std::shared_ptr<T0>)>; 

調用它像

rdt::Action<rdt::StatusResponse> callback; 

std::shared_ptr<rdt::StatusResponse> response = 
std::make_shared<rdt::StatusResponse> 
(rdt::errorcode::DEVICE_ID_OUT_OF_RANGE, std::string {"Device ID out 
of Range!"}); 

callback(response); 
return; 

這似乎是非常低效和昂貴(使用的std::shared_ptr發射後不管,此外,該程序需要返回庫函數,只是返回回來...) 現在我做了另一種方法:

void callback(std::unique_ptr<StatusResponse> response); 

std::unique_ptr<StatusResponse> response = 
std::make_unique<StatusResponse>(0, "success!"); 

callback(std::move(response)); 

然而,這仍然似乎是無效的,因爲我正在圍繞一個將被銷燬的對象構建一個包裝。

void callback(StatusResponse&& response); 

StatusResponse response {0, "Success!"}; 
callback(std::move(response)); 

是可能的,甚至

callback(StatusResponse {0, "Success!"}); 

所以,現在,我相當不確定的可能性。

第一個問題:結構中的std::move是否合適?

第二個問題:哪種解決方案將提供最佳的速度優勢?回調可能會被稱爲像

std::thread t(callback, StatusResponse {0, "Success!"}); 
t.detach(); 

我剛開始學習右值引用和智能指針所以任何幫助是極大的讚賞!

編輯: 我進行了測試,SergeyA似乎是正確的。 右值引用的方式產生以下調試輸出:

Constructor Called! 
Copy Constructor Called! 
Copy Constructor Called! 
Destructor Called! 
Destructor Called! 
Callback called! 
Called callback! 
Exiting caller! 
Exiting callback! 
Destructor Called! 

提供了一個移動的構造導致Copy Constructor Called被替換Move Constructor Called

回答

0

沒有,右值引用也不行 - 臨時會的陳述完成後刪除。實際上,最有效的方法是按值複製,但在結構上使用移動構造函數,並從臨時或結果創建它。

+0

感謝您的回答。你能確切地說明你的建議嗎?我正在努力理解你的真正含義。 – java4ever