Closed
Description
https://godbolt.org/z/z5E4eMGeW
#define _LIBCPP_ABI_BOUNDED_ITERATORS 1
bool test(std::span<int> s, std::span<const int> cs) {
auto it = s.begin();
auto jt = cs.begin();
static_assert(std::same_as<decltype(it == jt), bool>);
return (it == jt);
}
The above snippet's static_assert
passes, but the next line hard-errors when instantiating the expression (it == jt)
:
__iterator/bounded_iter.h:63:28: error: '__current_' is a private member of 'std::__bounded_iter<int *>'
63 | : __current_(__other.__current_),
|
The immediate culprit is that __bounded_iter<T>
claims to be implicitly convertible from __bounded_iter<U>
:
template <class _OtherIterator, class = __enable_if_t< is_convertible<_OtherIterator, _Iterator>::value > >
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT
: __current_(__other.__current_),
__begin_(__other.__begin_),
__end_(__other.__end_) {}
But it probably shouldn't claim to be convertible at all. __bounded_iter
should follow exactly the same pattern as __wrap_iter
in terms of how it implements its conversions and comparison operators. See "The economist’s $100 bill, and the virtue of consistency" (2022-01-20).