Для удовольствия и прибыли ™, я пишу класс trie в С++ (используя стандарт С++ 11).
У моего trie<T> есть итератор, trie<T>::iterator. (Все они фактически функционально const_iterator s, потому что вы не можете изменить trie value_type.) Объявление класса итератора выглядит примерно так:
template<typename T>
class trie<T>::iterator : public std::iterator<std::bidirectional_iterator_tag, T> {
friend class trie<T>;
struct state {
state(const trie<T>* const node, const typename std::vector<std::pair<typename T::value_type, std::unique_ptr<trie<T>>>>::const_iterator& node_map_it ) :
node{node}, node_map_it{node_map_it} {}
// This pointer is to const data:
const trie<T>* node;
typename std::vector<std::pair<typename T::value_type, std::unique_ptr<trie<T>>>>::const_iterator node_map_it;
};
public:
typedef const T value_type;
iterator() =default;
iterator(const trie<T>* node) {
parents.emplace(node, node->children.cbegin());
// ...
}
// ...
private:
std::stack<state> parents;
// ...
};
Обратите внимание, что указатель node объявлен const. Это потому, что (на мой взгляд) итератор не должен изменять node, на который он указывает; это просто итератор.
Теперь, в другом месте моего основного класса trie<T>, у меня есть функция стирания, которая имеет общую подпись STL - для удаления данных требуется iterator (и возвращает iterator к следующему объекту).
template<typename T>
typename trie<T>::iterator trie<T>::erase(const_iterator it)
{
// ...
// Cannot modify a const object!
it.parents.top().node->is_leaf = false;
// ...
}
Компилятор жалуется, потому что указатель node доступен только для чтения! Функция erase определенно должна изменить trie, на который указывает итератор, хотя итератор не должен.
Итак, у меня есть два вопроса:
- Должны быть публичные конструкторы
iterator?trie<T>имеет необходимые членыbegin()иend(), и, конечно,trie<T>::iteratorиtrie<T>являются общими друзьями, но я не знаю Не знаю, что такое конвенция. Чтобы сделать их частными, я бы решился на то, что у меня возникло желание удалитьconst"обещание" из конструктора итератора. - Каковы правильные семантики/соглашения
constотносительно итератора и его указательnodeздесь? Никто из меня никогда не объяснял это, и я не могу найти никаких учебных пособий или статей о паутина. Вероятно, это более важный вопрос, но для этого требуется много планирования и правильной реализации. Я полагаю, это можно было бы обойти, просто используя 1, но это принцип вещи!