Ich arbeite an einer Lib, die Art von wissenschaftlichen Berechnungen durchführen wird. Es ist beabsichtigt, mit GUIs verwendet werden und daher die Berechnungen asynchron durchgeführt werden und die GUI (oder was auch immer Warteschlange eine Aufgabe in die lib) erhalten einen Rückruf auf einem zuvor angegebenen std::function
. Diese Rückrufe werden immer einen kleinen Statusantwortobjekt erhalten, nämlichVerwenden von Rvalue-Referenzen für asynchronen Rückruf
struct StatusResponse {
StatusResponse(int respC, std::string respS): responseCode(respC),
responseString(std::move(respS)) {};
int responseCode;
std::string responseString;
};
Diese Rückrufe sind Feuer und vergessen, sie nichts zurück (void) und es besteht keine Notwendigkeit für eine weitere Aktion zu warten, ausgeführt durch der Rückruf Daher sind auch die StatusResponse-Objekte temporär. Es scheint, als gäbe es jetzt mehrere Möglichkeiten. Meine erste Idee, die Callback-Funktion wurde definiert, als
template<typename T0>
using Action = std::function<void(std::shared_ptr<T0>)>;
es Aufruf folgt wie
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;
Dies scheint ziemlich ineffizient und teuer (Verwendung von std::shared_ptr
für fire-and-forget, außerdem muss das Programm Rückkehr in der Library-Funktion, nur um wieder zurück ...) Nun kochte ich einen alternativen Weg nach oben:
void callback(std::unique_ptr<StatusResponse> response);
std::unique_ptr<StatusResponse> response =
std::make_unique<StatusResponse>(0, "success!");
callback(std::move(response));
Dies scheint jedoch immer noch ineffektiv zu sein, weil ich eine Hülle um ein Objekt baue, das sowieso zerstört wird.
void callback(StatusResponse&& response);
StatusResponse response {0, "Success!"};
callback(std::move(response));
ist möglich oder sogar
callback(StatusResponse {0, "Success!"});
So, jetzt bin ich ziemlich unsicher über diese Möglichkeiten.
Erste Frage: Ist die std::move
in der Struktur geeignet?
Zweite Frage: Welche Lösung bietet den besten Geschwindigkeitsvorteil? Der Rückruf wird wahrscheinlich wie
genannt werdenstd::thread t(callback, StatusResponse {0, "Success!"});
t.detach();
Ich begann das Lernen über rvalue Verweise und intelligente Zeiger nur so ist jede Hilfe sehr dankbar!
EDIT: Ich führte einen Test und SergeyA scheint richtig zu sein. Die rvalue Referenz Art und Weise erzeugt die folgende Debugging-Ausgabe:
Constructor Called!
Copy Constructor Called!
Copy Constructor Called!
Destructor Called!
Destructor Called!
Callback called!
Called callback!
Exiting caller!
Exiting callback!
Destructor Called!
einen Umzug Konstruktor Bereitstellung führt zu Copy Constructor Called
durch Move Constructor Called
ersetzt
Danke für Ihre Antwort. Könnten Sie präzisieren, was Sie genau vorschlagen? Ich kämpfe um zu verstehen, was du wirklich meinst. – java4ever