2009-06-30 2 views
7

Я написал свой собственный шаблон контейнера с итератором. Как реализовать const_iterator?C++: Как написать const_iterator?

template <class T> 
class my_container { 
private: 
    ... 

public: 
    my_container() : ... { } 
    ~my_container() { } 

    class iterator : public std::iterator<std::bidirectional_iterator_tag, T> { 
    public: ... 

ответ

4

Единственное различие должно быть, когда вы разыменовываются константный итератор вы получаете константную ссылку, а не ссылку на объект в контейнере.

+1

Что относительно методов, которые принимают итераторы в качестве аргументов или возвращают итераторы? Я должен перегрузить их для const_iterators? Похоже на кучу повторяющегося кода. –

+0

итераторы должны быть конвертируемыми в const_iterators, поэтому вам не придется перегружать, если вам нужен только const_iterator. Вы выполняете функции типа begin(), end(), но нет никакого способа обойти это, поскольку const также является частью подписи метода. – 2009-06-30 06:54:05

+2

@ Posco Grubb: Нет. Если у вас есть методы, которые принимают итераторы, то их шаблоны. Метод должен работать на все, что действует как итератор. Если для этого метода требуется итератор, а не const_iterator, компилятор будет генерировать соответствующую ошибку. –

2

Я нахожу самый простой способ реализации итераторов boost::iterator. Если вы хотите, чтобы свернуть свой собственный, я думаю, что подпись должна быть:

class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const T> { 

с осуществлением такой же (если вы используете reference_type и так далее в подписях функции)

+0

Я с удивлением обнаружил, что iterator_traits :: const_iterator> :: value_type is int, а не int const (T, а не const T в вашем коде). Я думаю, что с const имеет смысл. Тем не менее, нижняя строка заключается в том, что если вы хотите соответствовать стандартным контейнерам, вам нужно использовать неконстантный T. – 2009-06-30 06:52:30

+0

. Важно, чтобы с помощью итератора const вы не могли использовать его для изменения переработанной коллекции. Таким образом, T или const T & являются подходящими. Использование const с просто T не требуется (так как возврат будет копией) –

+0

Ну, если вы хотите указать, что значение-значение не является константой, вы должны указать все параметры: class const_iterator: public std :: итератор . Я бы пошел с краткости (с некоторой дополнительной защитой от ошибок присваивания/равенства), а не с соответствием с вектором STL, но это сложный выбор с точки зрения дизайна. –

0

Roger Pate, value_types являются "просто". Я подозреваю, что вы увидите const, если вы посмотрите на iterator_traits :: const_iterator> :: reference, который, я думаю, будет «const int &».

Смежные вопросы