This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

3623. Uses of std::reverse_iterator with containers should not require manually including <iterator>

Section: 24.5.1.1 [reverse.iterators.general] Status: New Submitter: Jiang An Opened: 2021-10-23 Last modified: 2022-01-29

Priority: 3

View all issues with New status.

Discussion:

Currently it is unspecified whether the definitions of std::reverse_iterator and its related operators are available in <vector>, <array>, etc. So, it's unspecified now whether the following program is well-formed because it's unspecified whether the equality operator is available:

#include <vector>

int main()
{
  auto v = std::vector<int>(42);
  for (auto it = v.rbegin(); it != v.rend(); ++it);
  for (auto it = std::rbegin(v); it != std::rend(v); ++it);
}

Such underspecification also leaves the guarantee that std::rbegin, std::rend, std::crbegin, and std::crend are available in some other headers seems not so meaningful. In order to guarantee these function templates can be used meaningfully with containers, users are still required to include <iterator> manually.

I think the standard should guarantee that wherever the member rbegin (that returns std::reverse_iterator) or std::rbegin is provided, the definitions of std::reverse_iterator and its related operators are also provided. This strategy is already implemented by libc++, libstdc++, and MSVC STL, and thus I believe we should standardize it to reduce uncertainty for users.

Note that the situation for std::reverse_iterator is different from LWG 1361(i), because every operation on std::size_t is still valid when the typedef-name itself is absent, but == and != on std::reverse_iterator fail if the corresponding declarations are unavailable.

[2022-01-29; Reflector poll]

Set priority to 3 after reflector poll.

Proposed resolution:

This wording is relative to N4901.

  1. Modify 24.5.1.1 [reverse.iterators.general] as indicated:

    -1- Class template reverse_iterator is an iterator adaptor that iterates from the end of the sequence defined by its underlying iterator to the beginning of that sequence.

    -?- In addition to being available via inclusion of the <iterator> header, class template reverse_iterator and function templates in 24.5.1.8 [reverse.iter.cmp] and 24.5.1.9 [reverse.iter.nonmember] are available when any of the following headers are included: <array> (23.3.2 [array.syn]), <deque> (23.3.4 [deque.syn]), <forward_list> (23.3.6 [forward.list.syn]), <list> (23.3.8 [list.syn]), <map> (23.4.2 [associative.map.syn]), <regex> (28.6.3 [re.syn]), <set> (23.4.5 [associative.set.syn]), <span> (23.7.2.1 [span.syn]), <stacktrace> (19.6.2 [stacktrace.syn]), <string> (27.4.2 [string.syn]), <string_view> (27.3.2 [string.view.synop]), <unordered_map> (23.5.2 [unord.map.syn]), <unordered_set> (23.5.5 [unord.set.syn]), and <vector> (23.3.10 [vector.syn]).