Для удовольствия и прибыли ™, я пишу класс 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, но это принцип вещи!