Вздох: здесь есть уровень хакерства, разработанный для того, чтобы скрыть тот факт, что концептуально то, что вы хотите сделать, не может быть сделано автоматически в C ++, потому что оно не понимает дисперсию. Некоторые другие языки (включая Ocaml) делают.
Если у вас есть функтор (это шаблонный класс для программистов на C ++), вопрос заключается в том, как он и различные функции ведут себя с дисперсией параметра, например при преобразовании из T в T const. То, что вы действительно хотите, это:
List<T> --> List<T const>
другими словами, вы хотите, чтобы функтор List был ковариантным. Но нет, это не так ... на самом деле шаблон List вообще не является функтором, потому что функторы должны сохранять структуру, а преобразование не отражается должным образом. В свою очередь это означает, что либо шаблоны C ++ сломаны, либо концепция const нарушена, потому что система типов, которая не поддерживает параметрический полиморфизм, нарушается спецификацией:)
Предоставление const_iterator не решает эту проблему, оно просто исправляет разрыв. Где версия volatile и const_volatile? Как насчет двойных косвенных указаний?
Если вы не понимаете двойной косвенности: рассмотрите дерево векторов T, это два шаблона:
Tree<Vector<T>>
Лучшее решение здесь - отказаться от поддержки const_iterator. Просто не беспокойся. В любом случае это сбивает с толку: как насчет "const vector"? Что это такое? Вектор, который вы не можете сделать длиннее, но он по-прежнему позволяет писать элементы?
Фактическое требование заключается в том, чтобы преобразовать коммутируют, например:
vector<T> const == vector<T const>
[или они не коммутируют, если преобразование противоречиво]
Тот факт, что этого не происходит, показывает, что вектор не является функторным, другими словами, шаблоны не могут эффективно использоваться для параметрического полиморфизма. Если вы действительно хотите связать свои узлы в узел, рассмотрите шаблоны с аргументами функции и спросите о дисперсии возвращаемого типа и параметров функции и о том, как это может повлиять на контейнер. Хороший пример - как составить две функции, чтобы они работали над парой. Что, если они мутаторы, как тогда работает "const"?