On Sunday 13 July 2014 17:04:09 Eric Niebler wrote:
On 7/13/2014 2:48 AM, Peter Dimov wrote:
Andrey Semashev wrote:
Perhaps Eric could provide more context on why Boost.Proto needs recursive reference wrappers? Frankly, the requirement looks strange to me.
Generic code that does
boost::reference_wrapper<T> r = boost::ref( t );
is broken when t is a reference_wrapper.
Right. That's exactly what I argued in committee. Doug Gregor was the only person I was able to convince. C'est la vie. It's also why Proto broke.
Proto doesn't *need* the old behavior, strictly speaking. But the part of proto that builds expressions, proto::make_expr, was designed around the old semantics. See http://bit.ly/1oUbgZr. proto::result_of::make_expr is a metafunction for computing the result of the proto::make_expr function. It interprets reference types as the types of things to be held by reference, and non-reference types to be held by value. When calling proto::make_expr at run-time, each argument to be held by reference must be wrapped in boost::ref. It uses the generic-friendly invariant of boost::ref that Peter references above.
I've already hacked Proto and it's tests to accommodate the change, and the tests are turning green again, so it's not a huge deal. But end user code will have to change. Xpressive didn't break, and it looks like Spirit didn't break, so the scope of the breakage might be small. Hard to say.
Thank you Eric. Am I right that the user's code that uses proto::result_of::make_expr (or any other Proto metafunction for result type computation) won't be broken? I'm omitting for now the possibility that the user's code could use the reference wrapper like in the Peter's code sample. From your changes to Proto tests I could not see what kind of changes would be required on the user's side.