2013-12-24 4 views
0

여기 내 코드입니다, 나는 자바 스크립트처럼 C++에서 클로저를 테스트하고 싶습니다. 왜 컴파일러가이 메시지를 산출합니까? 람다 광장 요구하는 이유C++ 람다 값을 캡처 할 수 없습니다

당신은 대괄호에서 캡처를 지정해야
#include <iostream> 
    #include <functional> 
    std::function<bool(int)> returnLambda(int a){ 
     auto b = 1; 
     auto c = 2; 

     return [&](int x) 
     { return x*(b++)+c+a == 0;}; 
    } 
    auto f = returnLambda(21); 
    int main(){ 
     auto c = f(1); 
     auto b = f(1); 

     std::cout<<c<<b<<std::endl; 
     return 0; 
    } 
+3

'[]'은 캡처 변수를 저장하는 곳입니다. – yngccc

+1

답변으로 해결되는 문제가 있지만 새로운 문제가 발생하면 질문을 변경하지 마십시오. 다른 글에서 새로운 질문을하십시오. –

+0

괜찮습니다. 대단히 감사합니다. –

답변

6

은, 그건 "testLambda.cpp은 : testLambda.cpp : 8 : 11 : 에러 람다 함수에 '이'가 포착되지" 처음부터 대괄호. 당신은 참조를 캡처 할 수 있습니다 :

[a,b,c] (int x) ... 

하거나 섞어 :

[&a,&b,&c] (int x) ... 

또는 값에 의해

[a,&b,c] (int x) ... 

또는 당신은 당신이 사용하는 모든 캡처 할 수 있습니다 :

[&] (int x) ... // by reference 
[=] (int x) ... // by value 

가변을 캡처하도록 선택한 경우

[=] (int x) mutable ... 
+0

고마워, 내 코드를 조금 바꾼다.하지만 그게 Segmentation fault이다. 문제는 람다 함수의 'a'이다. –

+1

@Ryan_Liu - 람다가있을 때 객체가 살아 있는지 확인하는 것보다 참조로 캡처하면 – pstrjds

+0

귀하의 답변에 명확하게 설명해 준 원래 코멘트를 삭제했습니다. 값으로 캡쳐하고 값을 변경할 때는 변경 가능해야합니다. – pstrjds

1

벤자민 린들리는 C에서 람다의 선언에 대한 답변을 ++ 제공 : 값을 기준으로 할 수는 있지만, 그것을 수정해야합니다, 당신은 그것을 변경할 수 있도록해야합니다.

기술적으로 말해 C++ 람다를 사용하여 JavaScript 클로저를 재현 할 수 없습니다.

로컬 함수에서 사용하는 JS 외부 변수는 GC 메커니즘으로 보호됩니다.

그러나 C++에서는 참조로 변수를 캡처하면 참조 된 변수가 파괴되어 쉽게 세분화 오류/액세스 위반이 발생할 수 있습니다.

#include <iostream> 
#include <functional> 
std::function<bool(int)> returnLambda(int a){ 
    auto b = 1; 
    auto c = 2; 

    return [&](int x) 
    { return x*(b++)+c == 0;}; 
} 
auto f = returnLambda(21); 
int main(){ 
    auto c = f(1); 
    auto b = f(1); 

    std::cout<<c<<b<<std::endl; 
    return 0; 
} 

가 returnLambda (행 돌아간 다음 심하게 충돌한다)의 변수들 A, B 및 C가 파괴된다 (그들의 스택 위치가 다른 것에 의해 사용된다) 함수 f (예를 들어

이,)가 호출됩니다.

+0

그런 동작을 원할 경우 로컬 변수를 공유 포인터로 만들고 람다 값으로 값을 캡처하십시오. –

+0

@Benjamin Lindley 예, C++에서 * closure를 시뮬레이션하는 기술이 있지만 실제로는 시뮬레이션입니다. JS의 클로저는 함수 참조 + 호출 프레임 체인 (힙의 객체)에 대한 참조입니다. 따라서 기본적으로 모든 기술자는 하나 또는 그 이상의 형태로 해당 호출 프레임 체인을 시뮬레이트합니다. –

관련 문제