> 백엔드 개발 > C++ > C Lambda에서 이동 캡처를 구현하는 방법은 무엇입니까?

C Lambda에서 이동 캡처를 구현하는 방법은 무엇입니까?

Linda Hamilton
풀어 주다: 2024-12-26 13:35:10
원래의
788명이 탐색했습니다.

How to Implement Move Capture in C   Lambdas?

Lambdas의 이동 캡처

질문:

이동 캡처를 어떻게 구현합니까? C 11 람다에서는 rvalue 참조라고 알려져 있나요? 예를 들면 다음과 같습니다.

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

std::function<void(void)> example = [std::move(myPointer)] {
   *myPointer = 4;
};
로그인 후 복사

답변:

C 14의 일반화된 람다 캡처

C 14에서 일반화된 람다 캡처는 이동 캡처를 허용합니다. 이제 이 코드가 유효합니다.

using namespace std;

auto u = make_unique<some_type>(some, parameters);  
go.run([u = move(u)] { do_something_with(u); }); 
로그인 후 복사

객체를 람다에서 다른 함수로 이동하려면 람다를 변경 가능하게 만드세요.

go.run([u = move(u)] mutable { do_something_with(std::move(u)); });
로그인 후 복사

C 11의 Move Capture에 대한 해결 방법

도우미 함수 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에서 일반화된 람다 캡처 에뮬레이션

또 다른 해결 방법은 캡처()에 의해 제공됩니다. 함수:

#include <cassert>
#include <memory>

int main() {
    std::unique_ptr<int> p{new int(0)};
    auto lambda = capture(std::move(p),
        [](std::unique_ptr<int>& p) { return std::move(p); });
    assert(lambda());
    assert(!lambda());
}
로그인 후 복사

capture는 다음과 같이 구현됩니다.

#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));
}
로그인 후 복사

이 솔루션은 캡처된 유형을 복사할 수 없는 경우 람다 복사를 방지하여 런타임 오류를 방지합니다.

위 내용은 C Lambda에서 이동 캡처를 구현하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿