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); }