Boost logo

Boost :

Subject: Re: [boost] [GSoC][Phoenix3] Regarding mutability of arguments passed to phoenix expressions
From: Eric Niebler (eric_at_[hidden])
Date: 2010-06-11 11:12:46


On 4/28/2010 1:26 PM, Eric Niebler wrote:
> On 4/28/2010 10:19 AM, Mathias Gaunard wrote:
>> Thomas Heller wrote:
>>> Regarding arguments to phoenix expressions there are two
>>> possibilities. The first is: Arguments are mutable. The current
>>> phoenix is implemented to be able to this.
>
> We now have lambdas in C++0x. IMO, we should be paying attention to
> the default semantics of lambdas which, IIRC, accept their arguments
> by value(?), and have special syntax for accepting their arguments
> by reference. Someone should correct me if I got that backwards. In
> the long haul, I think this will satisfy the Principle of Least
> Surprise.

Following up on this ... I was conflating lambda arguments with captured
variables that appear in the lambda body. I just looked over the draft
standard, and variables are captured by reference by default and need
special syntax to capture them by value. 5.1.2/14-15:

> 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. The
> declaration order of these members is unspecified. The type of such a
> data member is the type of the corresponding captured entity if the
> entity is not a reference to an object, or the referenced type
> otherwise. [ Note: if the captured entity is a reference to a
> function, the corresponding data member is also a reference to a
> function. —end note ]
>
> 15 An entity is captured by reference if it is implicitly or
> explicitly captured but not captured by copy. It is unspecified
> whether additional unnamed non-static data members are declared in
> the closure type for entities captured by reference.

This seems pretty clear to me, so I think Phoenix has it backwards wrt
variable capture. I find it interesting that functions are called out as
a special case, but not arrays or abstract types. Presumably it's simply
an error to try to capture these by value, but the standard could simply
DWIM.

As for the lambda arguments, Phoenix can take no guidance from the
standard since the built-in lambdas require you to define an argument
list, making them monomorphic. We could aim for consistency with the
capture behavior and pass by reference, or be consistent with std::bind
which uses rvalue refs and perfect forwarding (darn), or TR1 bind and
boost::bind which accepts parameters by value.

Given the choices, I think pass-by-value makes the most sense.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk