13

The code that fails for clang (while gcc seems okey with it)

    int arr[] { 111, 222, 333};
    ranges::subrange(
        ranges::begin(arr),ranges::end(arr) );

It looks like clang claim gcc's subrange do not have begin function?!

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/iterator_concepts.h:953:35: note: and 'std::ranges::subrange<int *, int *, std::ranges::subrange_kind::sized> &' does not satisfy '__member_begin'

      requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>

                                  ^

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/iterator_concepts.h:937:33: note: because '__detail::__decay_copy(__t.begin())' would be invalid: no member named 'begin' in 'std::ranges::subrange<int *, int *, std::ranges::subrange_kind::sized>'

          { __detail::__decay_copy(__t.begin()) } -> input_or_output_iterator;

                                       ^

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/iterator_concepts.h:953:59: note: and 'std::ranges::subrange<int *, int *, std::ranges::subrange_kind::sized> &' does not satisfy '__adl_begin'

      requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>

[LIVE]


part of gcc's iterator_concepts.h :

   namespace __detail
   {
     template<typename _Tp>
       constexpr decay_t<_Tp>
       __decay_copy(_Tp&& __t)
       noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>)
       { return std::forward<_Tp>(__t); }
  
     template<typename _Tp>
       concept __member_begin = requires(_Tp& __t)
         {
           { __detail::__decay_copy(__t.begin()) } -> input_or_output_iterator;
         };
  
     void begin(auto&) = delete;
     void begin(const auto&) = delete;
  
     template<typename _Tp>
       concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>>
         && requires(_Tp& __t)
         {
           { __detail::__decay_copy(begin(__t)) } -> input_or_output_iterator;
         };
  
     // Simplified version of std::ranges::begin that only supports lvalues,
     // for use by __range_iter_t below.
     template<typename _Tp>
       requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>
       auto
       __ranges_begin(_Tp& __t)
       {
         if constexpr (is_array_v<_Tp>)
           {
             static_assert(sizeof(remove_all_extents_t<_Tp>) != 0,
                           "not array of incomplete type");
             return __t + 0;
           }
         else if constexpr (__member_begin<_Tp&>)
           return __t.begin();
         else
           return begin(__t);
       }
  
     // Implementation of std::ranges::iterator_t, without using ranges::begin.
     template<typename _Tp>
       using __range_iter_t
         = decltype(__detail::__ranges_begin(std::declval<_Tp&>()));
  
   } // namespace __detail
sandthorn
  • 2,770
  • 1
  • 15
  • 59
  • This looks like clang instantiating constraints too early. – T.C. Oct 16 '20 at 22:42
  • Any updates on this? Perhaps a bug report? – Kelemen Máté May 25 '22 at 20:31
  • @KelemenMáté It seems clang has to use only its own `libc++` with ``, not `stdlibc++`. The `` has been supported since clang 13 => CE[[xT8xosj8o](https://compiler-explorer.com/z/xT8xosj8o)]. Though you can always come back to `range-v3` on github. – sandthorn Jul 03 '22 at 08:28
  • 2
    This is a known Clang bug: https://github.com/llvm/llvm-project/issues/44178 – Jeffrey Bosboom Aug 18 '22 at 03:38
  • @JeffreyBosboom Well, it seems there is a patch already merged but a corperate regression rises due to commercial code amongst facebook and the intel compiler. I hope they sort their things out soon. [d483730d8c3f](https://reviews.llvm.org/rGd483730d8c3f) – sandthorn Aug 22 '22 at 05:22

0 Answers0