How is this pointer captured?

Consider the following code:

struct S { int x; void f() { auto l = [&](){ x = 42; }; //this is implicitly captured here } }; 

Section 5.1.2 / 14 states:

An entity is captured by the copy if it is implicitly committed, and the default is = or if it is explicitly captured with a capture that does not include &.

Therefore, I conclude that this not captured by the copy. But then in ยง 5.1.2 / 15:

An object is captured by reference if it is implicitly or explicitly captured, but not captured by the copy. It is not indicated whether declared additional elements of a non-static element are declared in the closure type for objects captured by the link.

this is fixed by reference. But now in ยง5.1.2 / 17 it says:

[...] If this fixed, each use of odr this converted to access the corresponding unnamed data element of the closure type, [...]

As far as I understand, this means that the closure type must have an unnamed data element corresponding to the this pointer. But since this is fixed by reference, the standard does not require such an element. What am I wrong about?

+6
source share
3 answers

The standard does a poor job of making it clear, but this can only be captured by a copy. It cannot be captured by the lvalue reference, since this is an rvalue for C ++ 11 ยง9.3.2 / 1.

Please note that the standard prohibits explicitly fixing this by reference, because (a) the grammar does not allow &this in the capture list, since this lexically a keyword and not an identifier, and (b) 5.1. 2/8 prohibits explicit capture of this when the default value is = .

It would seem that there is a mistake in the specification that this can be implicitly fixed when the default value is & , which indicates its capture by reference.

+1
source

I think you found a specification error - you are correct that this is fixed by reference, but the text that you found in ยง5.1.2 / 17 should only be applied if this copy.

As Casey says, it really doesn't make sense to grab this from a link.

0
source

Of course, such a data item exists in a closure type. Capture by value and capture by reference require a data item in a closure type. The only question is its type:

 T /* maybe const and/or volatile */ * captured_this; 

vs

 T /* maybe const and/or volatile */ * const & captured_this; 

Since this cannot change, there is no noticeable difference between them.

0
source

All Articles