Я реализую пользовательский контейнер с STL-подобным интерфейсом. Я должен предоставить регулярный итератор и константный итератор. Большая часть кода для двух версий итераторов идентична. Как я могу избежать этого дублирования?Как избежать дублирования кода, реализующего константные и неконстантные итераторы?
Например, мой контейнерный класс Foo
, и я реализую FooIterator
и FooConstIterator
. Оба итератора должны предоставить такие методы, как operator++()
, которые идентичны.
Мой вопрос аналогичен How do I remove code duplication between similar const and non-const member functions?, но ответ на этот вопрос специфичен для методов const и non-const, особенно для аксессуаров. Я не вижу, как это может быть обобщено на проблему итератора.
Должен ли я иметь FooIterator
исходя из FooConstIterator
и расширять его дополнительными неконстантными методами? Это либо приводит к скрытию виртуальных методов или методов, которые здесь кажутся неуместными.
Возможно, FooIterator
должно содержать FooConstIterator
. Хотя этот подход уменьшает дублирование реализации, он, похоже, повторно вводит множество определений методов шаблонов.
Есть ли умная технология шаблона для генерации двух итераторов из одного определения? Или, может быть, есть способ - содрогнуться - использовать препроцессор, чтобы искоренить эти почти одинаковые классы.
Я пробовал посмотреть мою локальную реализацию STL, чтобы увидеть, как она справляется с этим. Есть так много вспомогательных классов, что у меня проблемы с созданием дизайна, но похоже, что функциональность просто дублируется.
В предыдущих проектах мой пользовательский контейнер был построен поверх стандартного контейнера STL, поэтому мне не пришлось предоставлять свои собственные итераторы. В этом случае это не вариант.
Но в STL классы-итераторы определяются как классы-члены контейнеров, поэтому std :: vector :: iterator действителен. Код Мэтта Аустерна определяет класс slist_iterator как внешний класс slist. –
user8385554
@ user8385554: Я думаю, что идея состоит в том, что контейнер Slist от Matt Austern имел бы typedef для 'iterator' и' const_iterator', чтобы сделать итераторы доступными, как если бы они были типами членов. –