首页 >后端开发 >C++ >如何在 C Lambda(C 11 和 C 14)中实现移动捕获?

如何在 C Lambda(C 11 和 C 14)中实现移动捕获?

Barbara Streisand
Barbara Streisand原创
2024-12-17 20:56:12819浏览

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

C 11 Lambda 中的移动捕获

C 14 中的广义 Lambda 捕获

C 14 引入了广义 lambda 捕获,支持移动捕获。在 C 14 中,类似以下的代码将是有效的:

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

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

请注意,如果需要将对象从 lambda 移动到另一个函数,则 lambda 必须标记为可变:

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

C 11 中移动捕获的解决方法

在 C 11 中,可以使用辅助函数来实现移动捕获make_rref 创建对所需值的右值引用:

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

使用 make_rref 函数捕获 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() );
}

请注意,此解决方法使 lambda 可复制,这在捕获不可复制的对象时可能会导致问题。

在 C 中模拟通用 Lambda 捕获11

模拟广义 lambda 捕获的另一种方法涉及定义捕获函数:

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

使用 capture 通过移动捕获值:

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

此解决方案提供一种更简洁的方法,如果捕获的类型不可复制,则禁用复制 lambda。

以上是如何在 C Lambda(C 11 和 C 14)中实现移动捕获?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn