https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- The problem overload is this one: template<typename _Tp> inline _Expr<_BinClos<__shift_left, _Constant, _ValArray, _Tp, _Tp>, typename __fun<__shift_left, _Tp>::result_type> operator <<(const _Tp& __t, const valarray<_Tp>& __v) { typedef _BinClos<__shift_left, _Constant, _ValArray, _Tp, _Tp> _Closure; typedef typename __fun<__shift_left, _Tp>::result_type _Rt; return _Expr<_Closure, _Rt>(_Closure(__t, __v)); } That deduces _Tp as x and so tries to instantiate valarray<x> to see if __v can be initialized from std::endl, which causes the "invalid abstract return type" outside the immediate context. It can be fixed using enable_if (or __gnu_cxx::__enable_if since this is C++98 code) to reject invalid types for valarray, maybe using __is_abstract. I just need to figure out the best place to put it, and how many of the other overloaded operators are affected. It might make sense to make the first argument a non-deduced context, so we only use this operator when the RHS is really a valarray, rather than matching for anything on the LHS and then trying to convert the RHS to a valarray. I don't know if that would break real code using valarray.