https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116

--- Comment #2 from TC <rs2740 at gmail dot com> ---
I don't think this has anything to do with `end`. Consider the following code:

#include <ostream>

template<class T> struct foo {
    T f();
    void g(T);
};
template<class T> void operator<<(const T&, const foo<T>&) {}

struct x : public std::ostream
{
  virtual void flush() = 0;
};

void bar(x& os)
{
  os << std::endl;
}

I don't have access to 4.8.0, but this compiles on 4.7.3 and fails on 4.8.1+.
(In the <valarray> case, std::operator<<(const T&, const valarray<T>&) is
picked up by ADL.)

Deduction for this operator<< function template succeeds: `T` is deduced to be
`x` from the left operand; the right operand is a non-deduced context because
the supplied argument names a function template. Then substitution takes place,
and we instantiate valarray<x> (whose definition is needed to decide if it can
be constructed from std::endl), which triggers a hard error because you can't
return or take an abstract type by value. This is not diagnosed in GCC 4.7.3,
likely due to PR51184.

Reply via email to