Heim >Backend-Entwicklung >C++ >Wie kann ich Move Capture in C Lambdas (C 11 und C 14) erreichen?

Wie kann ich Move Capture in C Lambdas (C 11 und C 14) erreichen?

Barbara Streisand
Barbara StreisandOriginal
2024-12-17 20:56:12852Durchsuche

How Can I Achieve Move Capture in C   Lambdas (C  11 and C  14)?

Move Capture in C 11 Lambda

Generalisierte Lambda Capture in C 14

C 14 führt generalisierte Lambda Capture ein und ermöglicht die Move Capture. In C 14 ist Code wie der folgende gültig:

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

// move the unique_ptr into the lambda
go.run( [ u = move(u) ] { do_something_with( u ); } ); 

Beachten Sie, dass das Lambda als veränderbar markiert werden muss, wenn Sie das Objekt vom Lambda in eine andere Funktion verschieben müssen:

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

Problemumgehung für die Bewegungserfassung in C 11

In C 11 kann die Erfassung nach Bewegung mithilfe einer Hilfsfunktion make_rref erreicht werden Dadurch wird eine R-Wert-Referenz auf den gewünschten Wert erstellt:

#include <cassert>
#include <memory>
#include <utility>

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

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

Verwenden Sie die Funktion make_rref, um den Wert im Lambda zu erfassen:

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

Beachten Sie, dass diese Problemumgehung das Lambda kopierbar macht kann Probleme beim Erfassen nicht kopierbarer Objekte verursachen.

Emulierung der generalisierten Lambda-Erfassung in C 11

Ein weiterer Ansatz zur Emulation einer verallgemeinerten Lambda-Erfassung besteht in der Definition einer Erfassungsfunktion:

#include <utility>

template <typename T, typename F>
class capture_impl
{
    T x;
    F f;
public:
    // ... implementation
};

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

Verwenden Sie Erfassung, um den Wert durch Bewegung zu erfassen:

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

Diese Lösung bietet Ein saubererer Ansatz, der das Kopieren des Lambda deaktiviert, wenn der erfasste Typ nicht kopierbar ist.

Das obige ist der detaillierte Inhalt vonWie kann ich Move Capture in C Lambdas (C 11 und C 14) erreichen?. 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