
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