http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49022
Paolo Carlini <paolo.carlini at oracle dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |daniel.kruegler at | |googlemail dot com --- Comment #16 from Paolo Carlini <paolo.carlini at oracle dot com> 2011-06-14 12:04:56 UTC --- I had another look at this issue. Something I didn't realize at the time is that simply adding begin() and end() overloads taking a const _Expr& is not going to work in practice for the usages we care about, like the range-based for-loop, unless one manages somehow to pass the *same* temporary _Expr to both. I think we have an issue with that, I don't know if it's in the specs of the range-based for-loop vs the valarray case at issue, or just in the GCC implementation of the latter. Anyway, if I add the overloads: template<class _Clos, typename _Tp> inline const _Tp* begin(const _Expr<_Clos, _Tp>& __ex) { return std::__addressof<const _Tp>(__ex()[0]); } template<class _Clos, typename _Tp> inline const _Tp* end(const _Expr<_Clos, _Tp>& __ex) { return std::__addressof<const _Tp>(__ex()[0]) + __ex.size(); } Then, the snippet: std::valarray<int> v1{ 0, 1, 2, 3, 4 }, v2{ 5, 6, 7, 8, 9}; for (int i : v1 + v2) { std::cout << i << std::endl; } compiles but then misbehaves at compile-time, per valgrind too: apparently we don't have a proper range. Note that the following misbehaves exactly in the *same way*, and this appears to support my conjecture that we have a problem somewhere with two different temporary _Expr passed to the begin and end overloads: for (auto b = std::begin(v1 + v2), e = std::end(v1 + v2); b < e; ++b) { std::cout << *b << std::endl; } Maybe we should somehow point out this specific point in LWG 2058?