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

Reply via email to