http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49021
Jason Merrill <jason at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|ASSIGNED |RESOLVED
Resolution| |INVALID
--- Comment #12 from Jason Merrill <jason at gcc dot gnu.org> 2011-05-20
21:25:50 UTC ---
This is a bug in BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION.
The GCC bugfix meant that where previously
true ? boost::foreach_detail_::make_probe(getv()) : (getv())
had the type "vector", now it has type "const vector".
5.16/3 says:
Otherwise (i.e., if E1 or E2 has a nonclass type, or if they both have class
types but the underlying classes are not either the same or one a base class of
the other): E1 can be converted to match E2 if E1 can be implicitly converted
to the type that expression E2 would have if E2 were converted to a prvalue (or
the type it has, if E2 is a prvalue).
"const vector" cannot be converted to make_probe<vector>, but
make_probe<vector> has an operator vector&, so it can be converted to const
vector, so the type of the conditional expression is const vector.
Here's a reduced example:
template <class T>
void f (T&, int);
template <class T>
void f (T const&, ...);
struct A { };
struct B { operator A& () const; };
const A g();
int main()
{
f( (true ? B() : g()), 0);
}