
On 6/14/2010 4:09 PM, joel falcou wrote:
Eric Niebler wrote:
I was mistaken about falling foul of RVO. Here is what is happening. You have two domains in play, both with different generators. You compose some expressions in different domains, A and B. Proto decides the resulting expression R should be in domain B. Proto prefers things to be nice and uniform, so before making A a child of R, it puts it also into B's domain by applying B's generator. That causes the extra copy you're seeing. If A and B had had the same generator, no extra invocation of the generator would be performed.
Why does Proto put expression A into B's domain? Good question. It just seemed like the right thing to do when I wrote the code. Right now, that looks like a dubious decision. Lemme think on it for a bit
Don't know if it'll help you but, back in the day where subdomain didn't exist, NT2 used a as(a,b) function to make a comaptible with b. It was like :
template<class Y,class C,class X> static inline typename boost::proto::result_of:: make_expr < tags::as_ , containers::domain<typename Y::nt2_category_tag> , containers::expr<X,C> const& >::type const as( containers::expr<X,C> const& xpr, Y const& ) { return boost::proto:: make_expr < tags::as_ , containers::domain<typename Y::nt2_category_tag> > ( boost::cref(xpr) ); }
and it worked without any copy as a was stored as a reference in a special node.
This jogged my memory a bit. My reasoning at the time was that someone might want to use as_expr to explicitly put a proto expression into a particular domain -- something like your as() function. But in hindsight, a separate function for that might have been better. as_expr should just do one thing: adapt non-proto types to proto. If something is already a proto type, just leave it alone. If the user wants to apply some other domain's generator to it, she can just do that. I've made the change on trunk. This could potentially be a breaking change. For instance, it slightly changes the behavior of your as() function; it no longer will invoke Y's generator before making X a child of the new node. I don't think it makes a difference, but we'll see who hollers. -- Eric Niebler BoostPro Computing http://www.boostpro.com