Boost logo

Boost :

Subject: Re: [boost] [GSoC][Phoenix3] Regarding mutability of arguments passed to phoenix expressions
From: David Abrahams (dave_at_[hidden])
Date: 2010-06-11 11:49:25


At Fri, 11 Jun 2010 11:12:46 -0400,
Eric Niebler wrote:
>
> > 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:

I don't see how you draw that conclusion from the text below.

> > 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.

My understanding is that the only implicit captures happen when there
is a capture-default, i.e.:

   void f()
   {
       int a;

       []{ return a; } // error - no capture-default

       // capture-default is &
       [&]{ return a; } // a implicitly captured by reference

       // implicit capture and capture-default is =
       [=]{ return a; } // a implicitly captured by copy

       // explicit capture with a capture that does not include &
       [a]{ return a; } // a captured by copy
   }

> 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.

why not perfect forwarding?

-- 
Dave Abrahams
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