왜 이것을 람다에서 참조 ( ‘& this’)로 캡처 할 수 없습니까? //

this람다에서 캡처 (개체 속성 수정) 하는 올바른 방법 은 다음과 같습니다.

auto f = [this] () { /* ... */ };

그러나 나는 내가 본 다음과 같은 특징이 궁금합니다.

class C {
    public:
        void foo() {
            // auto f = [] () { // this not captured
            auto f = [&] () { // why does this work?
            // auto f = [&this] () { // Expected ',' before 'this'
            // auto f = [this] () { // works as expected
                x = 5;
            };
            f();
        }

    private:
        int x;
};

내가 혼란스럽고 대답하고 싶은 이상한 점은 다음과 같은 이유입니다.

auto f = [&] () { /* ... */ }; // capture everything by reference

그리고 내가 this참조로 명시 적으로 캡처 할 수없는 이유 :

auto f = [&this] () { /* ... */ }; // a compiler error as seen above.


답변

[&this]작동하지 않는 이유 는 구문 오류 때문입니다. 의 각 쉼표로 구분 된 매개 변수는 다음 lambda-introducercapture같습니다.

capture:
    identifier
    & identifier
    this

&this구문 상 허용되지 않음을 알 수 있습니다 . 허용되지 않는 이유 this는 작은 const 포인터 이기 때문에 참조 로 캡처하고 싶지 않기 때문 입니다. 값으로 만 전달하고 싶을 것입니다. 따라서 언어는 this참조로 캡처 하는 것을 지원하지 않습니다 .

캡처에 this명시 적으로 사용할 수 [this]는 AS lambda-introducer.

첫 번째 capture는 다음 중 하나 일 수 있습니다 capture-default.

capture-default:
    &
    =

이것은 내가 사용하는 모든 것을 참조 ( &) 또는 값 ( =) 별로 자동으로 캡처하는 것을 의미합니다. 그러나 처리 this는 특별합니다. 두 경우 모두 이전에 제공된 이유 때문에 값으로 캡처됩니다 (기본 캡처를 사용하더라도 &일반적으로 참조로 캡처).

5.1.2.7/8 :

이름 조회 (3.4)를 위해 this(9.3.2) 의 유형과 값을 결정하고 비 정적 클래스 멤버를 참조하는 id- 표현식을 (*this)(9.3.1), 복합 문 [OF]을 사용하여 클래스 멤버 액세스 표현식 으로 변환합니다. THE LAMBDA]는 lambda-expression의 맥락에서 고려됩니다.

따라서 람다는 멤버 이름을 사용할 때 둘러싸는 멤버 함수의 일부인 것처럼 작동하므로 (예에서 name 사용과 같이 x) this멤버 함수와 마찬가지로 “암시 적 사용”을 생성 합니다.

lambda-capture가 capture-default를 포함하는 경우 lambda-capture &의 식별자 앞에 &. lambda-capture가 capture-default를 포함하는 =경우 lambda-capture는 포함하지 않아야하며 포함 된
this각 식별자 앞에 &. 식별자 또는 this람다 캡처에서 두 번 이상 나타나지 않아야합니다.

당신이 사용할 수 있도록 [this], [&], [=]또는 [&,this]A와 lambda-introducer캡처하는 this값으로 포인터를.

그러나 [&this][=, this]잘못 형성된다. 마지막 경우에 gcc 는 오류 [=,this]explicit by-copy capture of ‘this’ redundant with by-copy capture default아니라이를 경고 합니다.


답변

표준은 &this캡처 목록에 없기 때문에 :

N4713 8.4.5.2 캡처 :

lambda-capture:
    capture-default
    capture-list
    capture-default, capture-list

capture-default:
    &
    =
capture-list:
    capture...opt
    capture-list, capture...opt
capture:
    simple-capture
    init-capture
simple-capture:
    identifier
    &identifier
    this
    * this
init-capture:
    identifier initializer
    &identifier initializer
  1. 람다 캡처를 위해 식은 잠재적으로 다음과 같이 로컬 엔터티를 참조합니다.

    7.3 this 표현은 잠재적으로 * this를 참조합니다.

따라서 표준 보증 this*this유효하며 &this유효하지 않습니다. 또한, 촬영 this촬상 수단 *this(a 좌변 객체 자체 임) 을 참조하여 , 대신 캡처 this포인터 !