Почему ForwardIterators должны моделировать DefaultConstructible?

Я не могу найти стандартных алгоритмов, которые продемонстрировали бы требование построения по умолчанию ForwardIterator.

Есть ли какая-либо фактическая причина для этого, или я могу игнорировать его?

Ответ 1

Это облегчает использование этих итераторов для стандартных алгоритмов и пользователей-клиентов.

Например (помните, что RandomAccessIterator является подтипом ForwardIterator):

template <class RandomAccessIterator>
  void sort ( RandomAccessIterator first, RandomAccessIterator last )
{
    RandomAccessIterator pivot, i, j;
    //do your sorting algorithm        
}

Если они не были конструктивными по умолчанию, вам нужно назначить их first или last только для его компиляции.

Вам не нужно, чтобы оно было установлено на значение по умолчанию. Любое использование такого неинициализированного итератора undefined. Не то, что было бы разумно добавить некоторые проверки, особенно в отладочных сборках.

И нет, вы не должны бросать конструктор по умолчанию. Это будет технически совместимо, но многие алгоритмы неожиданно потерпят неудачу.

Ответ 2

Из моей копии проекта:

24.2.5 Итераторы вперед [forward.iterators]

1 Класс или встроенный тип X удовлетворяет требованиям передового итератора, если

[...]

- X удовлетворяет требованиям DefaultConstructible (20.2.1),

а затем:

20.2.1 Требования к аргументу шаблона

2 В общем случае конструктор по умолчанию не требуется. Определенный контейнер подписчики функции члена класса определяют конструктор по умолчанию как аргумент по умолчанию. T() должно быть четко определенным выражением (8.5), если одно из этих сигнатур вызывается с использованием аргумента по умолчанию (8.3.6).

Здесь есть две вещи:

  • В первой строке мы говорим о том, что по умолчанию ctor редко требуется (что почти отвечает на ваш вопрос)
  • Требование, вероятно, является намеком на то, что семантика итератора должна быть совместима с указателями, последняя по умолчанию конструктивна (читай, чтобы не нарушать существующий код).