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.