Пользовательский контейнер с пользовательским итератором не работает, если контейнер определен как const - PullRequest
0 голосов
/ 15 января 2011


Более-менее все есть в теме.
когда у меня

func(my_cont& c)
{ c.begin() };

все работает, но

func(const my_cont& c)
{ c.begin() };

не работает, компилятор утверждает, что не может преобразовать это в const my_cont <..> .... из my_cont <..>

Каковы требования к контейнеру и моему пользовательскому итератору для обработки этого?

Ответы [ 5 ]

4 голосов
/ 15 января 2011

Ваш класс контейнера должен иметь две реализации begin () и end () - один возвращающий итератор и другой возвращающий const_iterator:

      iterator begin ();
const_iterator begin () const;
      iterator end ();
const_iterator end () const;

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

1 голос
/ 15 января 2011

Вот хорошая статья о написании итераторов:
http://www.aristeia.com/Papers/CUJ_June_2001.pdf

Как отмечали большинство людей, вам нужна const-версия begin () и end (), которая возвращает const_iterator.

Большинство людей забыли, что итератор должен иметь возможность неявно преобразовывать в const_iterator.В противном случае трудно получить константный итератор из недорогого объекта (без большого количества неприятных приведений).

 my_cont   data;
 for(my_cont::const_iterator loop = data.begin(); loop != data.end(); ++loop)
 {
     /* STUFF */
 }

Примечание выше: вышеприведенные вызовы будут фактически вызывать бесплатные версии begin () и end().Но они назначаются на const_iterator.Таким образом, ваши итераторы должны быть конвертируемыми в const_iterator, чтобы вышеприведенный код работал (Примечание: неявного преобразования из const_iterator в итератор не требуется. Это должно принимать явное const_cast, поскольку оно по своей природе опасно).

1 голос
/ 15 января 2011

Вам нужно добавить const begin(), примерно так:

class my_cont
{
public:
    const_iterator begin() const;
};

Вам также потребуется определить тип const_iterator.

0 голосов
/ 15 января 2011

Вы можете вызывать только функции-члены const для объекта const (или функции-члены volatile для объекта volatile).Компилятор сообщает, что iterator my_cont::begin() const отсутствует.

0 голосов
/ 15 января 2011

Именно поэтому STL реализует cost_iterator для контейнеров. Просто проверьте, как это реализовано в STL, я не уверен, что вы можете найти какое-либо лучшее решение.

...