Subject: Re: [boost] [core] Breaking change to boost::ref in 1.56
From: Peter Dimov (lists_at_[hidden])
Date: 2014-07-14 03:20:41
Agustín K-ballo Bergé wrote:
> As mentioned in the pull request, cases like the following:
> int i= 0;
> boost::reference_wrapper<int> r = boost::ref(boost::ref(i));
> were performing "accidental collapsing", as it triggers an implicit
> conversion followed by a (possibly elided) copy construction.
This works because of another boost::ref 'feature', it returns a const
reference_wrapper which allows the outer boost::ref to bind to it. That
const return is probably a mistake, now that I think of it, but it's too
late to change it now.
In fact, of the four ref/cref combinations, three happen to work as if
reference collapsing overloads are present.
What makes this hard is that I think that Eric is right and that the
reference collapsing overloads should never have been added to std::ref. It
should be obvious that nobody would write code like the above on purpose;
there's absolutely no point in calling boost::ref twice when one call would
do. It's similar to something like
int x = std::cref( 5 );
which is also something that used to work and is broken now, and also
something that nobody would write except by mistake.
The motivation for the reference collapsing overloads must come from
examples taken from real code in which ref somehow gets applied to something
that already is a reference_wrapper but not to ref(x) directly, and the code
needs the result to be a flattened reference_wrapper for some reason. So far
I've been unable to think of such an example. I wonder if anyone has ever
encountered it. This feature looks like a typical committee invention to me.