Я сталкивался с этой проблемой несколько раз и хотел бы узнать, есть ли простой способ или шаблон, который я могу использовать для его решения.Как проходить через контейнер в другом классе?
Представьте себе древовидную структуру, в которой каждый узел содержит контейнер STL (вектор) указателей на детей. Я хочу, чтобы клиентский код мог пересекать это дерево и перебирать дочерние контейнеры для доступа к другим частям.
Моя проблема заключается в том, что я хочу поддерживать инкапсуляцию для своих узлов, в то же время позволяя клиентам легко видеть всех дочерних элементов для этого узла. Я также хочу убедиться, что если клиент получает ссылку на const для корневого узла в дереве, то доступ к последующим частям дерева также является константой.
Должен ли я попытаться сделать класс итератора для моего типа узла, иметь метод итераторов вектора вершин узла, или есть более элегантный шаблон, который мне не хватает?
Edit: Я хочу еще раз подчеркнуть, что в то время как я вижу некоторые хорошие идеи, представленные, у меня есть контейнеры указателей к другим узлам. Возврат vector<node *>::const_iterator
не будет препятствовать вызовам клиентов неконстантными методами на узле. Он только защищает самих указателей от указания на разные объекты.
Будет ли это работать, если node_list - это вектор указателей на узлы, и я хочу, чтобы клиент имел только указатели на узлы константы? –
«код знает, что это итератор с произвольным доступом», интересный момент, но в то же время код также знает, что это именно «вектор :: const_iterator». Тем не менее, гораздо проще использовать 'operator +', не задумываясь, чем присваивать итератору 'vector :: const_iterator' вместо' node :: const_iterator', не задумываясь. Интересно, есть ли случай для адаптера итератора, который ничего не делает, кроме «понизить» итератор, который он переносит в определенную категорию. Затем вы можете вернуть 'make_forward_iterator (children_.begin())' или некоторые из них. –
@Steve: Поскольку категория является частью типа итератора, вам нужно будет сделать преобразование в typedef. Я думаю, вы могли бы сделать это довольно легко, но используя класс 'template forward_iterator_wrapper: private RealIteratorT {};'. Там могут быть проблемы; Я не думал об этом подробно. –