iterator and const_iterator

Discussion in 'C++' started by John Harrison, Nov 20, 2005.

  1. 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
    John Harrison, Nov 20, 2005
    #1
    1. Advertising

  2. > 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
    peter steiner, Nov 20, 2005
    #2
    1. Advertising

  3. John Harrison wrote in news:ay3gf.3573$ 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.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Nov 20, 2005
    #3
  4. peter steiner wrote:
    >>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.


    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.

    >
    > -- peter
    >


    john
    John Harrison, Nov 20, 2005
    #4
  5. Rob Williscroft wrote:
    > John Harrison wrote in news:ay3gf.3573$ 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.


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

    john
    John Harrison, Nov 20, 2005
    #5
  6. John Harrison

    Cy Edmunds Guest

    "John Harrison" <> wrote in message
    news:ay3gf.3573$...
    >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.

    --
    Cy
    http://home.rochester.rr.com/cyhome/
    Cy Edmunds, Nov 20, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. CoolPint
    Replies:
    3
    Views:
    730
    CoolPint
    Dec 13, 2003
  2. Replies:
    2
    Views:
    363
    Ferdi Smit
    Oct 23, 2005
  3. Mark P
    Replies:
    2
    Views:
    703
    Bart van Ingen Schenau
    Jun 15, 2006
  4. flopbucket
    Replies:
    1
    Views:
    694
    flopbucket
    Jun 21, 2006
  5. Victor Bazarov

    iterator vs const_iterator

    Victor Bazarov, Jul 21, 2006, in forum: C++
    Replies:
    3
    Views:
    505
    Thorsten Kiefer
    Jul 21, 2006
Loading...

Share This Page