Title
`move_iterator` should not define `iterator_category`
Status
new
Section
[move.iterator]
Submitter
Jay Ghiron

Created on 2026-09-23.00:00:00 last changed yesterday

Messages

Date: 2026-09-26.12:45:11

Proposed resolution:

This wording is relative to N5054.

  1. Modify [move.iterator] as indicated:

    namespace std {
      template<class Iterator>
      class move_iterator {
      public:
        using iterator_type = Iterator;
        using iterator_concept = see below ;
        using iterator_category = see below ; // not always present
        using value_type = iter_value_t<Iterator>;
        using difference_type = iter_difference_t<Iterator>;
        using pointer = Iterator;
        using reference = iter_rvalue_reference_t<Iterator>;
        
        […]
    
      private:
        Iterator current = Iterator(); // exposition only
      };
    }
    

    -1- The member typedef-name `iterator_concept` is defined as follows: […]

    -2- The member typedef-name `iterator_category` is declared if and only if the qualified-id iterator_traits<Iterator>::iterator_category is valid and denotes a type. In that case, `iterator_category` denotes

    1. (2.1) — `random_access_iterator_tag` if the type iterator_traits<Iterator>::iterator_category models derived_from<random_access_iterator_tag>, and

    2. (2.2) — iterator_traits<Iterator>::iterator_category otherwise.

Date: 2026-09-23.00:00:00

Consider the following program:

#include<iostream>
#include<iterator>

struct S
{
  void m() & 
  {
    std::cout << "&\n";
  }
  
  void m() && 
  {
    std::cout << "&&\n";
  }
};

int main()
{
  S x[1];
  std::move_iterator<S*>a{x};
  a->m();
  (*a).m();
}

According to [input.iterators] the expressions a->m and `(*a).m` should always be equivalent for the requirements of Cpp17InputIterator to be satisfied. However, `move_iterator` fails to meet that requirement here when it promises to do so by defining `iterator_category` to a type derived from `input_iterator_tag`. That is, `iterator_category` in this example should not be defined. Note that a removal of the deprecated operator-> would not make it satisfy the requirements. It may be possible to allow `move_iterator` to have `iterator_category` if it can be proven that a->m would never be valid or if the difference is unobservable. However, it seems simplest to just delete `iterator_category`.

History
Date User Action Args
2026-09-26 12:45:11adminsetmessages: + msg16625
2026-09-23 00:00:00admincreate