Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah Saya Boleh Mencapai Move Capture dalam C Lambdas (C 11 dan C 14)?

Bagaimanakah Saya Boleh Mencapai Move Capture dalam C Lambdas (C 11 dan C 14)?

Barbara Streisand
Barbara Streisandasal
2024-12-17 20:56:12806semak imbas

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

Move Capture dalam C 11 Lambda

Generalized Lambda Capture dalam C 14

C 14 memperkenalkan generalized lambda capture, mendayakan move capture. Dalam C 14, kod seperti berikut akan sah:

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

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

Perhatikan bahawa jika anda perlu mengalihkan objek dari lambda ke fungsi lain, lambda mesti ditandakan sebagai boleh ubah:

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

Penyelesaian untuk Move Capture dalam C 11

Dalam C 11, menangkap melalui gerakan boleh dicapai menggunakan fungsi pembantu make_rref yang mencipta rujukan rnilai kepada nilai yang dikehendaki:

#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) };
}

Gunakan fungsi make_rref untuk menangkap nilai dalam lambda:

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() );
}

Perhatikan bahawa penyelesaian ini membuat lambda boleh disalin, yang mungkin menyebabkan masalah apabila menangkap objek yang tidak boleh disalin.

Meniru Tangkapan Lambda Umum dalam C 11

Pendekatan lain untuk meniru tangkapan lambda umum melibatkan penentuan fungsi tangkapan:

#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) );
}

Gunakan tangkapan untuk menangkap nilai dengan bergerak:

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() );
}

Penyelesaian ini menyediakan pendekatan yang lebih bersih yang melumpuhkan penyalinan lambda jika jenis yang ditangkap bukan boleh disalin.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mencapai Move Capture dalam C Lambdas (C 11 dan C 14)?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn