Juan Antonio
Juan Antonio

Reputation: 2614

Problems with an iterator and an const_iterator in the same class

I'm writing a class "translator" and I need two iterators, one constant and other more normal. This is the interesting zone of code:

...

iterator begin() {
  iterator i;
  i.puntero=palabras.begin();
  return i;
}
iterator end(){
  iterator i;
  i.puntero=palabras.end();
  return i;
}
...
const_iterator begin() const  {
  const_iterator i;
  i.puntero=palabras.begin();
  return i;
}
const_iterator end() const {
  const_iterator i;
  i.puntero=palabras.end();
  return i;
}
...

There are more code but I think that isn't interesting.

Well, I need use the iterators in a for loops and is in this moment when the code fail:

  #Work fine
  for(Traductor::iterator it=traductor.begin(); it!=traductor.end(); ++it)
    cout << it->first << endl;

  #Don't work
  for (Traductor::const_iterator it=traductor.begin(); it!=traductor.end(); ++it)
    cout << it->first << endl;

The error is:

 error: conversion from ‘Traductor::iterator’ to non-scalar type ‘Traductor::const_iterator’ requested    for (Traductor::const_iterator it=traductor.begin(); it!=traductor.end(); ++it)

And i don't know how make to the program uses the const_iterator in the second loop and don't try to use the normal.

Any idea? Thanks you so much.

Solution adopted:

Finally, If I use a const traductor isn't necessary to changing the name to end and begin methods but if traductor isn't not constant i need use cend and cbegin methods.

Example:

  #When is constant:
  const Traductor tradConst = traductor;

for (Traductor::const_iterator it=tradConst.begin(); it!=tradConst.end(); ++it)

  #When isn't, use diferent methods to differentiate:
  //for (Traductor::const_iterator it=traductor.cbegin(); it!=traductor.cend(); ++it)

...

So, I have:

const_iterator begin() const {...}
const_iterator end() const {...}
iterator begin() {...}
iterator end(){...}

Useful when I use constant and non-constant objects, and when I want use const and non-const iterator in a non-const object I will change the name of the methods:

const_iterator cbegin() const {...}
const_iterator cend() const {...}
iterator begin() {...}
iterator end(){...}

Thanks you so much guys!

Upvotes: 0

Views: 634

Answers (3)

Jarod42
Jarod42

Reputation: 217085

Unless traductor is const, traductor.begin() returns an iterator.

You have to provide a constructor of const_iterator which takes an iterator (or add an operator const_iterator in iterator).

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

It seems that object traductor is not a constant object. so as result non constant overloaded functions begin and end are called in this loop

for (Traductor::const_iterator it=traductor.begin(); it!=traductor.end(); ++it)
    cout << it->first << endl;

You could write

for (Traductor::const_iterator it= const cast<const Traductor &>( traductor ).begin(); it!=const cast<const Traductor &>( traductor ).end(); ++it)
    cout << it->first << endl;

Another approach is to define functions cbegin and cend specially for selecting the const_iterator.

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385108

The type of the thing you're initialising has very little (read: no) bearing on how the function call in the initialiser will be resolved.

That means, when traductor is non-const, your non-const begin() and end() will always be used!

You can fix this by allowing iterator to implicitly convert to const_iterator. There is also the option of adding cbegin() and cend() functions that explicitly, always, return const_iterator. This is "safer" in a number of cases.

The standard library containers do both.

Upvotes: 1

Related Questions