Ответ 1
Это длинная и искривленная история.: -)
Да, карта, набор, список и т.д. сохраняют счетчики для подачи постоянного времени size()
. До С++ 11 ни один из контейнеров не требовался для хранения счетчиков, поскольку их size()
должен быть постоянным временем, но не должен быть постоянным временем. В стандарте "должно" означает, может быть, может быть, нет, и "обязательно" означает определенно.
На практике в С++ 98/03 все контейнеры имели постоянное время size()
, за исключением list
, даже map
и set
(с помощью счетчика). Это сделало для некоторого ужасно не переносимого кода, используя list
, некоторые из которых принимали постоянное время size()
, а некоторые из них принимали постоянное время "сращивание некоторых из других." Обе эти операции не могут быть постоянными, реализация должна была выбрать один или другой.
В С++ 11 стандарт был изменен, чтобы сказать, что size()
должно быть постоянным временем. Однако в то же время был введен также forward_list
. И вся точка forward_list
должна быть оптимизацией list
. И комитет не хотел повторять ошибку list::size()
, иногда являясь постоянным временем, а иногда и линейным временем. Поэтому было принято решение не давать forward_list
a size()
вообще. Таким образом, клиенты никогда не станут жертвой неожиданного линейного времени size()
. Клиенты forward_list
, которые хотят сделать это вычисление, все еще имеют distance(fl.begin(), fl.end())
в своем распоряжении, если они захотят сделать это.
См. N2543 для получения более подробной информации о причине отказа size()
от forward_list
.