https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to TC from comment #2) > 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. Hmm, there is a SFINAE issue here then. We should reduce this further. A simple reduction based on the description works still: template<class T> struct foo { T f(); void g(T); }; template<class T> void operator<<(const T&, const foo<T>&) {} template<class T> void operator<<(const T&, void (*)(void)) {} void endl(int); void endl(void); struct x { virtual void flush() = 0; }; void bar(x& os) { os << endl; } --- CUT --- Also I had confused end and endl earlier which is why I had messed up.