Skip to content

<iterator>: The implementation of common_iterator::operator== seems to be wrong #2065

@hewillk

Description

@hewillk

MSVC-STL's implementation of common_iterator is similar to libstdc++, it defines operator== inside the class:

STL/stl/inc/iterator

Lines 930 to 940 in bd7adb4

template <class _OIter, sentinel_for<_Iter> _OSe>
requires sentinel_for<_Se, _OIter>
_NODISCARD friend bool operator==(const common_iterator& _Left, const common_iterator<_OIter, _OSe>& _Right) {
// clang-format on
#if _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(
_Left._Val._Contains != _Variantish_state::_Nothing && _Right._Val._Contains != _Variantish_state::_Nothing,
"common_iterators can only be compared if both hold a value");
#endif // _ITERATOR_DEBUG_LEVEL != 0
if (_Left._Val._Contains == _Variantish_state::_Holds_iter) {

and declares template common_iterator class as a friend:

STL/stl/inc/iterator

Lines 1008 to 1010 in bd7adb4

template <input_or_output_iterator _OIter, sentinel_for<_OIter> _OSe>
requires (!same_as<_OIter, _OSe> && copyable<_OIter>)
friend class common_iterator;

But according to the description of [class.friend#10]: "Friendship is neither inherited nor transitive."
This will cause the following valid code to be rejected (godbolt):

#include <iterator>

int main() {
  std::common_iterator<int*, std::unreachable_sentinel_t> it1;
  std::common_iterator<const int*, std::unreachable_sentinel_t> it2;
  return it1 == it2;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions