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 중국어 웹사이트의 기타 관련 기사를 참조하세요!