문제는 지역 변수가 어딘가에 저장되어 있기 때문에 (로컬의 "소유자"생존 람다에 의해 참조에 의해 캡처 될 때 C++ 람다는 즉, "upwards funarg"사건을 해결 할 수없는 것입니다 함수 결과로 반환 되었기 때문에).
람다가 참조로 변수를 캡처 할 때 C++는 참조 된 변수의 주소를 람다 코드가 사용하는 컨텍스트 구조에 저장하는 것입니다.
그러나 변수 자체는 지역 변수이며 람다가 만들어진 스택 프레임에 있습니다. 람다 객체가 단지 someOtherFunction
의 실행 중에 호출된다면 문제가 없지만, 람다가 이 떨어져서 저장되고에 저장되고 그것을 만든 스택 프레임에서 살아남는다. (또는 람다에서 참조 된 캡쳐 된 변수를 생성했다.)가 실행될 때 더 이상 존재하지 않는 변수를 참조합니다 (정의되지 않은 동작).
일반적으로 "위쪽 funarg"문제를 해결하려면 가비지 수집기가 필요하며 C++에는 가비지 수집기가 필요하지 않습니다.
당신은 어떤 경우에 할 수있는 "값"캡처, 그래서 람다는 자신의 개인 사본있을 것이다 무엇 : 당신은 또한 필요 복사 당신이 캡처 변경하려면 그러나이 경우에
foo([counter]() mutable { counter++; })
을 mutable
키워드를 사용하는 것이 좋습니다 ... 캡처 된 복사본을 수정하려는 경우 C++에 필요하기 때문입니다. 캡처 된 복사본은 람다 본문의 const
개체입니다.
불행히도 캡처 된 변수를 두 개의 람다 (예 : 동일한 캡처 변수에서 "증분 자"와 "감소 자"모두 생성)와 공유해야하는 경우 사본 사용은 실행 가능하지 않습니다. 이 작업을 수행하기 위해 수행 할 수있는 작업은 변수에 std::shared_ptr
의 값으로 캡처하는 것이며, 이는 참조 루프의 경우가 아닌 간단한 경우 가비지 수집기를 올바르게 대체합니다.
'someotherFunction'에서'lamb'을 실행하면'counter'가 여전히 유효하기 때문에이 함수가 작성되어야합니다. 그러나 'someotherFunction'이 람다를 저장하고 나중에 func이 반환 된 후에 람다가 실행되면 매달린 참조 문제가 생깁니다. –
하지만 아래의 주석을 보면 someotherFunction의 실행이 func 실행을 초과하면 올바르게 실행되지 않는 것으로 보입니다. – sublime
요점은 당신이 * inside *'func'에서'someotherFunction'을 호출하고 있다는 것입니다. 즉,'func'보다 더 오래 살 수는 없습니다. –