Subject: Re: [boost] [GSoC][Phoenix3] Regarding mutability of arguments passed to phoenix expressions
From: David Abrahams (dave_at_[hidden])
Date: 2010-06-11 12:27:25
At Fri, 11 Jun 2010 12:12:27 -0400,
Eric Niebler wrote:
> On 6/11/2010 11:49 AM, David Abrahams wrote:
> > 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.
> I went back, and you're right. 5.1.2/11-12 make it clear that implicit
> capture happens only when a default capture mode is specified. Good.
> That gives us an opportunity to add a new feature to Phoenix: default
> capture modes. I could see something like:
> ref[ phoenix-lambda-expression ]
> makes default capture by-ref, and
> val[ phoenix-lambda-expression ]
I would be cautious about emulating C++0x lambdas. I'm not sure yet
that they don't suck.
> makes it by-val. Under the hood, Phoenix would actually be storing every
> captured variable both by value and by reference.
!! Sounds expensive.
> ref and val simply
> change how the resulting tree is interpreted. In addition, we can let
> users pick and choose on a per-variable basis using the the ref(x) and
> val(x) on every use of the variable x within the expression.
> >> 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?
> Because it's too expensive to simulate in C++98.
Oh, I meant for 0x. Be cautious, also, about designing for C++98 at
the expense of a good 0x interface.
-- Dave Abrahams BoostPro Computing http://www.boostpro.com