2016-08-03 4 views
4

C++ 14 표준 초안 N4140 5.1.2.12 [expr.prim.lambda]의 예제를 이해할 수 없습니다.람다에서 캡처되지 않은 변수 사용

자동 저장 기간으로 명시 적으로 캡처하지 않는 관련 capture-default를 가진 lambda-expression (이것은 initcapture의 연관된 비 정적 데이터를 나타 내기 위해 발견 된 id 표현식을 제외합니다. 부재) (암시 적 실체를 캡처라고 즉,이 또는 가변) 화합물-if 문

  • ODR-사용 엔티티 또는
  • 이름 잠재적-평가 식 여기서의 실체 둘러싼 전체 식은 l의 도달 범위 내에서 선언 된 일반 람다 매개 변수에 의존합니다 ambda-expression.

[예 :

void f(int, const int (&)[2] = {}) { } // #1 
void f(const int&, const int (&)[1]) { } // #2 
void test() { 
    const int x = 17; 
    auto g = [](auto a) { 
    f(x); // OK: calls #1, does not capture x 
    }; 
    auto g2 = [=](auto a) { 
    int selector[sizeof(a) == 1 ? 1 : 2]{}; 
    f(x, selector); // OK: is a dependent expression, so captures x 
    }; 
} 

-end 예]

그러한 모든 내재적 캡처 엔티티 람다 식의 도달 범위 내에서 선언된다.

[참고 : 중첩 된 람다 식으로 엔티티를 암시 적으로 캡처하면 포함 된 람다 식 (아래 참조)에 의한 암시 적 캡처가 발생할 수 있습니다. 이것을 암시 적으로 odr-uses하면 암시 적 캡처가 발생할 수 있습니다. -end 노트]

나는 따라서 #1 호출이 오류 (캡처되지 변수를 사용하는 방법에 대한 뭔가)으로 이어질 것입니다 구 a lambda-expression with an associated capture-default의 시작은 어떤 암시 캡처를 금지해야한다고 생각했다 (그리고 그것은 코멘트에 의해 확인 된 것). 어떻게 작동합니까? f의 첫 번째 인수는 무엇입니까? test() 범위를 종료 한 후 g을 호출하면 어떻게 될까요? #1 서명을 void(const int&)으로 변경하면 어떻게됩니까?

-

UPD : 그것이 작동하는 방법의 설명에 대한 모든 감사합니다. 나중에이 사례에 대한 표준을 찾아보고 게시하려고 노력할 것입니다.

+1

'x'는 const 표현식입니다. ODR은 참조 때문에 # 2에서만 사용됩니다. – Jarod42

+1

즉,'g'는 몸이'{f (17); }'. –

답변

0

as T.C. 그의 의견에 따르면 컴파일시에 x이 알려져 있으므로 # 1은 캡처가 필요 없으므로 람다에 구워집니다. 컴파일 할 때 함수 f이 알려진 방법과 다르지 않으므로 캡처 할 필요가 없습니다. 당신은 지금, 스택에 변화에 따라서 될 수있는 상수의 주소를 전달하는 시도 int const &f의 서명을 변경하는 경우

나는 믿고, 그것은 값 또는 참조로 x을 캡처 필요합니다.