i was surprised the other day that when u pass references in lambda's they actually get copied when capturing by value. If u pass a pointer, the pointer gets copied, but not the pointee. However if u pass a reference also the thing the reference points to
get copied. Its the reverse what I would expect (atm) but oth the c++ committee often does that :(. But maybe someone has a powerful explanation?
On Wednesday, July 25, 2012 1:03:26 PM UTC-4, gas...@hotmail.com wrote:
> Hello all,
> i was surprised the other day that when u pass references in
> lambda's they actually get copied when capturing by value. If u pass
> a pointer, the pointer gets copied, but not the pointee. However if
> u pass a reference also the thing the reference points to
> i was surprised the other day that when u pass references in
> lambda's they actually get copied when capturing by value. If u pass
> a pointer, the pointer gets copied, but not the pointee. However if
> u pass a reference also the thing the reference points to get
> copied. Its the reverse what I would expect (atm) but oth the c++
> committee often does that :(. But maybe someone has a powerful
> explanation?
Here is a code snippet from Sams Learn C++ in One Hour a Day, 7th
Edition, which covers Lambda functions (and the C++11 standard
updates) and expressions, page 161, Listing 7.11:
> Here is a code snippet from Sams Learn C++ in One Hour a Day, 7th
> Edition, which covers Lambda functions (and the C++11 standard
> updates) and expressions, page 161, Listing 7.11:
{ Reformatted; please limit your lines to 70 characters -mod }
Since your first lambda (anonymous function) specifies 'capture
(i.e. pass) by value' the lambda function behaviour is consitent with
normal parameter passing in C++.
{ Your article lacks the context of what it's referring to.
Please include some quoting to establish the context. -mod }
{ Please limit your text to fit within 80 columns, preferably around 70,
so that readers don't have to scroll horizontally to read each line.
This article has been reformatted manually by the moderator. -mod }
Hi, not exactly sure I understand what you mean.
Your first lambda captures by value (i.e. [=]). So if you grab an entity
inside the lambda which is declared as a reference in the enclosing
environment you will get a copy of it since you implicitly have stated
that the environment should be passed by value into the lambda. This is
consistent with normal parameter passing.
I know that you asked for a reason for the behaviour (which I hope I
gave),not a ref to the standard, but here is the standard anyway:
------ 5.1.2 ------
14 An entity is captured by copy if it is implicitly captured and the
capture default is = or if it is explicitly captured with a capture that
does not include an &. For each entity captured by copy, an unnamed
nonstatic data member is declared in the closure type. Blah, blah ...
15 An entity is captured by reference if it is implicitly or explicitly
captured but not captured by copy. Blah, blah ...
------
In your case for your first lambda, point 14 is applicable.
Am 25.07.2012 19:03, schrieb gast...@hotmail.com:
> i was surprised the other day that when u pass references in
> lambda's they actually get copied when capturing by value. If u
> pass a pointer, the pointer gets copied, but not the pointee.
> However if u pass a reference also the thing the reference points
> to get copied. Its the reverse what I would expect (atm) but oth
> the c++ committee often does that. But maybe someone has a powerful
> explanation?
Actually I find the specified behaviour very intuitive: If you capture
by value, this behaves as like copy-initialization of a "by-value"
variable, if you capture by reference, this behaves like a
by-reference parameter of the referenced type. If we decide for either
of these parameter types, this decision does not depend on whether the
argument is a reference or not. In fact, references that enter
expressions *always* behave as if the reference had been removed
first, see [expr] p5:
"If an expression initially has the type “reference to T” (8.3.2,
8.5.3), the type is adjusted to T prior to any further analysis."
In regard to pointers, these are just objects that can be copied, so
they are copied via a = capture as well.
Both behaviours are so important as part of C++ that any different
deduction form would be controversial (I just add as a remark that
capture of "this" is one of the more irritating things).
A similar *analogy* applies to function template deduction by
argument: The = capture corresponds to deducing a parameter type from
this signature form:
template<class T>
void f(T);
This will always determine T to a non-reference type, irrespective of
the value category of the argument or whether the argument is a
reference type or not.
The & capture corresponds to deducing a parameter type from this
signature form:
template<class T>
void f(&T);
and will always bind directly to the referenced argument. Again, this
deduction does not depend on whether the argument is a referenced type
or not.