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-introducer
과 capture
같습니다.
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
람다 캡처를 위해 식은 잠재적으로 다음과 같이 로컬 엔터티를 참조합니다.
7.3 this 표현은 잠재적으로 * this를 참조합니다.
따라서 표준 보증 this
및 *this
유효하며 &this
유효하지 않습니다. 또한, 촬영 this
촬상 수단 *this
(a 좌변 객체 자체 임) 을 참조하여 , 대신 캡처 this
포인터 값 !