首頁 > 後端開發 > C++ > 如何在 C Lambda 中實現移動捕獲?

如何在 C Lambda 中實現移動捕獲?

Linda Hamilton
發布: 2024-12-26 13:35:10
原創
788 人瀏覽過

How to Implement Move Capture in C   Lambdas?

在Lambda 中移動捕獲

問題:

我們如何實現移動捕獲在C 111 lambda 中稱為右值引用?例如:

std::unique_ptr<int> myPointer(new int);

std::function<void(void)> example = [std::move(myPointer)] {
   *myPointer = 4;
};
登入後複製

答案:

C 14 中的廣義Lambda 捕獲

在廣義14 中,在廣義lambda capture 允許移動捕捉。此程式碼現在有效:

using namespace std;

auto u = make_unique<some_type>(some, parameters);  
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 中移動捕獲的解決方法

輔助函數make_rref 可以促進移動捕捉。其實作如下:

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

template <typename T>
struct rref_impl {
    rref_impl() = delete;
    rref_impl(T&& x) : x{std::move(x)} {}
    rref_impl(rref_impl& other)
        : x{std::move(other.x)}, isCopied{true}
    {
        assert(other.isCopied == false);
    }
    rref_impl(rref_impl&& other)
        : x{std::move(other.x)}, isCopied{std::move(other.isCopied)}
    {
    }
    rref_impl& operator=(rref_impl other) = delete;
    T& operator&&() {
        return std::move(x);
    }

private:
    T x;
    bool isCopied = false;
};

template<typename T> rref_impl<T> make_rref(T&& x) {
    return rref_impl<T>{std::move(x)};
}
登入後複製

make_rref 的測試案例:

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());
}
登入後複製

在C 11 模擬廣義Lambda Capture

在C 11 中模擬廣義Lambda Capture

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

捕獲實現如下:
#include <utility>

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

    template <typename ...Ts> auto operator()(Ts&& ...args)
        -> decltype(f(x, std::forward<Ts>(args)...)) {
        return f(x, std::forward<Ts>(args)...);
    }

    template <typename ...Ts> auto operator()(Ts&& ...args) const
        -> decltype(f(x, std::forward<Ts>(args)...)) {
        return f(x, std::forward<Ts>(args)...);
    }
};

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));
}
登入後複製

如果捕獲的類型不可複製,此解決方案可防止複製 lambda,從而避免運行時錯誤。

以上是如何在 C Lambda 中實現移動捕獲?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板