Heim >Backend-Entwicklung >C++ >Wie kann ich Objekte durch Verschieben in C-Lambda-Ausdrücken effizient erfassen?

Wie kann ich Objekte durch Verschieben in C-Lambda-Ausdrücken effizient erfassen?

DDD
DDDOriginal
2024-12-09 07:19:07719Durchsuche

How Can I Efficiently Capture Objects by Move in C   Lambda Expressions?

Bewegungserfassung in Lambda-Ausdrücken

Einführung

In C ist die Erfassung durch Bewegung, auch R-Wert-Referenz genannt, möglich für die effiziente Übertragung des Besitzes eines Objekts auf einen Lambda-Ausdruck. Diese Technik kann besonders in Situationen nützlich sein, in denen die Ressourcen des Objekts explizit innerhalb des Lambda verwaltet werden müssen.

Generalisierte Lambda-Erfassung in C 14

In C 14 bietet die verallgemeinerte Lambda-Erfassung eine elegante Lösung zur Bewegungserfassung. Mit dieser Funktion ist es möglich, einen Lambda-Ausdruck zu deklarieren, der eine Variable nach Wert mithilfe der Verschiebungssemantik erfasst:

using namespace std;

auto u = make_unique<some_type>(some, parameters);  

go.run([u = move(u)] { do_something_with(u); });

Dieser Ansatz verschiebt den Besitz von u in das Lambda und stellt so sicher, dass die Ressourcen ordnungsgemäß freigegeben werden. Wenn das Objekt außerdem aus dem Lambda verschoben werden muss, muss das Lambda als veränderlich deklariert werden.

Problemumgehung für Move Capture in C 11

In C 11 erfolgt die Move Capture nicht direkt unterstützt. Es gibt jedoch Techniken, die dieses Verhalten nachahmen können. Ein Ansatz besteht darin, eine Hilfsfunktion zu verwenden, um eine R-Wert-Referenz (rref) zu erstellen:

template <typename T>
struct rref_impl {
    rref_impl() = delete;
    rref_impl(T &&x) : x(std::move(x)) {}
    // ... (remaining implementation)
};

template<typename T> rref_impl<T> make_rref(T &&x) {
    return rref_impl<T>{std::move(x)};
}

Mit dieser Hilfsfunktion ist es möglich, ein Objekt durch Verschieben in einem Lambda zu erfassen:

unique_ptr<int> p{new int(0)};
auto rref = make_rref(std::move(p));
auto lambda = [rref]() mutable -> unique_ptr<int> { return rref.move(); };

Beachten Sie, dass das Lambda als veränderlich deklariert ist, um die Änderung der erfassten R-Wert-Referenz zu ermöglichen.

Emulierung der generalisierten Lambda-Erfassung in C 11

Ein weiterer Ansatz zur Emulation der verallgemeinerten Lambda-Erfassung in C 11 besteht darin, eine benutzerdefinierte Klasse zu verwenden, um eine Variable zu erfassen und eine Möglichkeit bereitzustellen, sie aus dem Lambda zu verschieben:

template <typename T, typename F>
struct capture_impl {
    T x;
    F f;
    // ... (remaining implementation)
};

template <typename T, typename F>
capture_impl<T,F> capture(T &&x, F &&f) {
    return capture_impl<T,F>(std::forward<T>(x), std::forward<F>(f));
}

Diese Klasse kann verwendet werden, um eine Variable durch Verschieben zu erfassen und eine Möglichkeit zum Aufrufen des Lambda bereitzustellen:

unique_ptr<int> p{new int(0)};
auto lambda = capture(std::move(p), [](unique_ptr<int> &p) { return std::move(p); });

Im Gegensatz zum vorherigen Ansatz ist dies Lambda ist nicht kopierbar, wenn der erfasste Typ nicht kopierbar ist. Dies verhindert mögliche Fehler beim Kopieren des Lambda.

Das obige ist der detaillierte Inhalt vonWie kann ich Objekte durch Verschieben in C-Lambda-Ausdrücken effizient erfassen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn