Reputation: 2614
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
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
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
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