Подтвердить что ты не робот

Являются ли константные итераторы еще злыми в С++ 14

Пункт 26 от Скотта Майерса "Эффективный STL" помечен как "Предпочитаю iterator до const_iterator, reverse_iterator и const reverse iterator".

Мысль о том, что некоторые формы insert() и erase() требуют ровно iterator, а преобразование из других типов является утомительным и подверженным ошибкам. Кроме того, сравнение iterator и const_iterator может быть проблематичным, в зависимости от реализации STL.

Книга была выпущена в 2001 году. Является ли совет в пункте 26 действительным с текущим состоянием gcc?

4b9b3361

Ответ 1

Стандарт С++ 14 (N3936) гарантирует, что iterator и const_iterator свободно сопоставимы (§23.2.1 [container.requirements.general]/p7):

В выражениях

i == j
i != j
i < j
i <= j
i >= j
i > j
i - j

где i и j обозначают объекты типа контейнера iteratorодин или оба могут быть заменены объектом контейнеров const_iterator, ссылаясь на тот же элемент без изменений в семантика.

Кроме того, функции-члены контейнера принимают const_iterator параметры как из С++ 11 (§C.2.13 [diff.cpp03.containers] - как это можно сделать из тега, это изменение из С++ 03):

Изменить: изменения подписи: от iterator до const_iterator параметров

Обоснование: Overspecification. Эффекты: сигнатуры следующих функций-членов изменились с принятия iterator на принятие a const_iterator:

  • insert(iter, val) для vector, deque, list, set, multiset, map, multimap
  • insert(pos, beg, end) для vector, deque, list, forward_list
  • erase(iter) for набор , мультимножеством , карта , multimap`
  • erase(begin, end) for набор , мультимножеством , карта , multimap`
  • все формы list::splice
  • все формы list::merge

Требования к контейнеру были аналогичным образом изменены для принятия итераторов const. Кроме того, легко получить базовый итератор от a std::reverse_iterator через его функцию-член .base(). Таким образом, ни одна из проблем, отмеченных в вопросе, не должна быть проблемой в соответствующем компиляторе.

Ответ 2

Совет был отменен, как видно из пункта 13 предстоящего Эффективного современного С++, который называется:

Предпочитают константы-константы для итераторов

Причина в том, что С++ 11 и С++ 14 добавляют несколько настроек, которые делают const_iterators более практичным:

С++ 11 добавляет

  • функции-члены cbegin() и cend() (и их обратные копии) для всех контейнеров стандартной библиотеки
  • Функции-члены с использованием итераторов для определения позиций (например, insert(), erase()) теперь принимают const_iterator вместо iterator

С++ 14 завершает это, добавляя не-члены cbegin() и cend() (и их обратные копии)