我正在研究一個將執行某種科學計算的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
感謝您的回答。你能確切地說明你的建議嗎?我正在努力理解你的真正含義。 – java4ever