Search code examples
c++iteratorconst-iterator

How can I use a overloaded const_iterator inside a class?


I'm doing a University project in C++, whose purpose is to learn how to use the diferent STL containers and their iterators.

In my program, I have a class with a set:

class ConjuntoDeLetras{
    private:
        set<Letra> letras;

    public:
        ConjuntoDeLetras();   
        ···
};

Inside the class, I have two nested class, iterator and const_iterator. (I don't know if it's the best way to make class iterators, but the teacher tell us that we need to do at this way):

class iterator{
    private:
        set<Letra>::iterator it;
    public:
        iterator();

        Letra operator*();

        ConjuntoDeLetras::iterator& operator++();

        ConjuntoDeLetras::iterator& operator+=(int num);

        bool operator==(const ConjuntoDeLetras::iterator &i);

        bool operator!=(const ConjuntoDeLetras::iterator &i);

        friend class ConjuntoDeLetras;
};

class const_iterator{
    private:
        set<Letra>::const_iterator it;
    public:
        const_iterator();

        Letra operator*();

        ConjuntoDeLetras::const_iterator& operator++();

        ConjuntoDeLetras::const_iterator& operator+=(int num);

        bool operator==(const ConjuntoDeLetras::const_iterator &i);

        bool operator!=(const ConjuntoDeLetras::const_iterator &i);

        friend class ConjuntoDeLetras;
};

Both iterator class methods works well. In ConjuntoDeLetras class we have the begin and end methods:

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

The problem is here. When I'm going to use the const_iterator we have problems:

ConjuntoDeLetras::const_iterator itL;

for(itL=L.begin(); itL!=L.end(); ++itL){
    CantidadLetras aux;
    aux.frecuenciaAbsoluta = 0;
    aux.frecuenciaRelativa = 0;
    aux.letra = (*itL).getLetra();

    salida.push_back(aux);
}

When I execute this code the compiler says that I don't have operator= for const_iterator to iterator. I know the reason of the problem, it's because the object L is a not const variable and uses the normal iterator begin() and end(). I thought about removing the final const of the functions but I can't overload the function only with the return type. I don't know what is the best solution. Here is the compiler error:

error: no match for ‘operator=’ (operand types are ‘ConjuntoDeLetras::const_iterator’ and ‘ConjuntoDeLetras::iterator’)
 for(itL=L.begin(); itL!=L.end(); ++itL){
                 ^

And the same error with the end().


Solution

  • You are missing the other ++ operator and the required typedefs to be an iterator.

    Plus, you need =default copy/move/assignments.

    Finally you need a converting constructor from your iterator to your const_iterator.

    Optionaly add two const_iterator::operator=(iterator) overloads (copy assign and move assign), plus const_iterator::operator==(iterator const&) and iterator==const_iterator similarly.