iterator and const_iterator

J

John Harrison

I there a reliable and generic method to convert a const_iterator to an
iterator (i.e. something like const_cast).

I ask because I'm writing some methods which take and return iterators.
A const version of the method takes and returns const iterators and the
non-const version takes and returns non-const iterators. I'd like to
avoid code duplication like this

class X
{
iterator some_method(iterator i)
{
...
}

const_iterator some_method(const_iterator i) const
{
return const_cast<X*>(this)->some_method(i);
}

}

But that only works if I can convert a const_iterator to the equivalent
iterator.

Answers or alternatives welcome.

john
 
P

peter steiner

class X
{
iterator some_method(iterator i)
{
...
}

const_iterator some_method(const_iterator i) const
{
return const_cast<X*>(this)->some_method(i);
}

}

even if this cast would be possible the const-qualified some_method
would always violate the constness if you modify the instance later on
inside the first non-const-qualified some_method.

are you sure that this does not happen? i don't see how the first
some_method overload could guarantee that after casting the constness
of this and the iterator argument away.

maybe i misunderstand your basic idea but as i see it in the example
your method could be templated for the iterator argument and should
then either be const-qualified or not, depending if you modify the
instance itself or not.

-- peter
 
R

Rob Williscroft

John Harrison wrote in in
comp.lang.c++:
I there a reliable and generic method to convert a const_iterator to an
iterator (i.e. something like const_cast).
Answers or alternatives welcome.

Defenitvly alternative, but ...

template < typename iterator >
iterator some_method( X const &that, iterator i );

class X
{
iterator some_method(iterator i)
{
return some_method( *this, i );
}

const_iterator some_method(const_iterator i) const
{
return some_method( *this, i );
}
}

template < typename iterator >
iterator some_method( X const &that, iterator i )
{
// real code here
}

Rob.
 
J

John Harrison

peter said:
even if this cast would be possible the const-qualified some_method
would always violate the constness if you modify the instance later on
inside the first non-const-qualified some_method.

I should have made that clear. some_method don't not itself modify
anything, but it may (in the non-const version) return an iterator to
the internals of X which could be used to modify an X object.

Many methods in the STL have this property, for instance the lower_bound
and upper_bound methods of std::map.
are you sure that this does not happen? i don't see how the first
some_method overload could guarantee that after casting the constness
of this and the iterator argument away.

maybe i misunderstand your basic idea but as i see it in the example
your method could be templated for the iterator argument and should
then either be const-qualified or not, depending if you modify the
instance itself or not.

Yes templates occurred to me after I'd posted, but I wonder if there is
any method that avoids essentially have two copies of the same code.

john
 
J

John Harrison

Rob said:
John Harrison wrote in in
comp.lang.c++:




Defenitvly alternative, but ...

template < typename iterator >
iterator some_method( X const &that, iterator i );

class X
{
iterator some_method(iterator i)
{
return some_method( *this, i );
}

const_iterator some_method(const_iterator i) const
{
return some_method( *this, i );
}
}

template < typename iterator >
iterator some_method( X const &that, iterator i )
{
// real code here
}

Rob.

Templates do the trick as far as avoiding writing the same code twice. I
guess that's the best that can be done.

john
 
C

Cy Edmunds

John Harrison said:
I there a reliable and generic method to convert a const_iterator to an
iterator (i.e. something like const_cast).

I ask because I'm writing some methods which take and return iterators. A
const version of the method takes and returns const iterators and the
non-const version takes and returns non-const iterators. I'd like to avoid
code duplication like this

class X
{
iterator some_method(iterator i)
{
...
}

const_iterator some_method(const_iterator i) const
{
return const_cast<X*>(this)->some_method(i);
}

}

But that only works if I can convert a const_iterator to the equivalent
iterator.

Answers or alternatives welcome.

john

If iterator is derived from const_iterator, which in many cases is perfectly
practical, then you can do this:

class X
{
private:
iterator some_method_impl(const_iterator i) {...} // cast as required
here
public:
iterator some_method(iterator i) {return some_method_impl(i);} // bit
slice argument
const_iterator some_method(const_iterator i) const {return
some_method_impl(i);} // bit slice result
};

Of course I don't know if this would work with your particular iterators.
With many iterators in my experience, the bit sliced version is actually the
same data.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top