[libcxx-commits] [PATCH] D99855: [libcxx] makes `iterator_traits` C++20-aware
Zoe Carver via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Apr 15 15:58:00 PDT 2021
zoecarver added inline comments.
================
Comment at: libcxx/include/iterator:725
+ using difference_type = typename _Ip::difference_type;
+ using pointer = typename __iterator_traits_member_pointer<_Ip>::type;
+ using reference = typename _Ip::reference;
----------------
ldionne wrote:
> For the primary template, `pointer` should be (http://eel.is/c++draft/iterator.traits#3.1):
>
> > If the qualified-id `I::pointer` is valid and denotes a type, then `iterator_traits<I>::pointer` names that type; otherwise, it names `void`.
>
> We shouldn't check for `operator->()`, so using `__iterator_traits_member_pointer<_Ip>` (which checks for `operator->()`) doesn't sound correct to me. We should also add a test that catches that: define a type `T` from which we could deduce `iterator_traits<T>::pointer` using `operator->()` but not otherwise, and confirm that `iterator_traits<T>::pointer` is `void`. Before fixing this comment, the result would have been whatever's deduced by `operator->`.
>
Yes, @ldionne you're right. Here's an example (from Arthur's godbolt) which catches this:
```
struct NoPointerMember {
struct iterator_category {};
struct value_type {};
struct difference_type {};
struct reference {};
value_type* operator->() const; // ignored, because B is not a LegacyInputIterator
};
static_assert(std::same_as<NoPointerMemberTraits::pointer, void>);
```
On both MSVC and GCC this compiles just fine, but we (currently) think the pointer type should be `value_type*`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D99855/new/
https://reviews.llvm.org/D99855
More information about the libcxx-commits
mailing list