Home > Backend Development > C++ > How Can I Achieve Move Capture in C Lambdas (C 11 and C 14)?

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

Barbara Streisand
Release: 2024-12-17 20:56:12
Original
822 people have browsed it

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

Move Capture in C 11 Lambda

Generalized Lambda Capture in C 14

C 14 introduces generalized lambda capture, enabling move capture. In C 14, code like the following will be valid:

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

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

Note that if you need to move the object from the lambda to another function, the lambda must be marked as mutable:

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

Workaround for Move Capture in C 11

In C 11, capturing by move can be achieved using a helper function make_rref that creates an rvalue reference to the desired value:

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

Use the make_rref function to capture the value in the 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() );
}
Copy after login

Note that this workaround makes the lambda copyable, which may cause problems when capturing non-copyable objects.

Emulating Generalized Lambda Capture in C 11

Another approach to emulate generalized lambda capture involves defining a capture function:

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

Use capture to capture the value by move:

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

This solution provides a cleaner approach that disables copying the lambda if the captured type is not copyable.

The above is the detailed content of How Can I Achieve Move Capture in C Lambdas (C 11 and C 14)?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template