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?

Reply via email to