iterator design help

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Rex_chaos

    iterator design help

    Hi there,
    I am writing an iterator for a container. Just like a typical
    iterator,

    template <typename ADT>
    class MyIter
    {
    ...
    MyContainer<ADT >& refc;
    public:
    MyIter(MyContai ner<ADT>& cont) :refc(a) {...}

    MyIter& begin() {...; return *this;}
    MyIter& end() {...; return *this;}
    MyIter& operator++() {...; return *this;}
    ...
    };

    While MyIter is applied to a template algorithm like std::transform,
    the copy constructor will be actived because of the reference to cont.
    It lowers effeciency a lot. Maybe I should use a pointer as instead
    for speed purpose

    ....
    MyContainer<ADT >* refc;
    public:
    MyIter(MyContai ner<ADT>& cont) :refc(a) {...}
    ....

    However, it is another problem. Suppose the container passed to the
    iterator has been released, refc will then become an invalid pointer
    !!! I can't release the pointer (refc) in the destructor because I
    don't know if any object own the container.
  • Victor Bazarov

    #2
    Re: iterator design help

    "Rex_chaos" <rex_chaos@21cn .com> wrote...[color=blue]
    > I am writing an iterator for a container. Just like a typical
    > iterator,
    >
    > template <typename ADT>
    > class MyIter
    > {
    > ...
    > MyContainer<ADT >& refc;
    > public:
    > MyIter(MyContai ner<ADT>& cont) :refc(a) {...}
    >
    > MyIter& begin() {...; return *this;}
    > MyIter& end() {...; return *this;}[/color]

    I think you're confused. "begin" and "end" should be members of
    the container, not of the iterator.
    [color=blue]
    > MyIter& operator++() {...; return *this;}
    > ...
    > };
    >
    > While MyIter is applied to a template algorithm like std::transform,
    > the copy constructor will be actived because of the reference to cont.[/color]

    I am not sure I understand the sentence above.
    [color=blue]
    > It lowers effeciency a lot. Maybe I should use a pointer as instead
    > for speed purpose
    >
    > ...
    > MyContainer<ADT >* refc;
    > public:
    > MyIter(MyContai ner<ADT>& cont) :refc(a) {...}
    > ...
    >
    > However, it is another problem. Suppose the container passed to the
    > iterator has been released, refc will then become an invalid pointer
    > !!! I can't release the pointer (refc) in the destructor because I
    > don't know if any object own the container.[/color]

    That's the problem with all iterators. They become invalid when the
    container they were iterating is destroyed. Simply document that
    behaviour and think no more of it.

    Victor


    Comment

    • Rex_chaos

      #3
      Re: iterator design help

      > > template <typename ADT>[color=blue][color=green]
      > > class MyIter
      > > {
      > > ...
      > > MyContainer<ADT >& refc;
      > > public:
      > > MyIter(MyContai ner<ADT>& cont) :refc(a) {...}
      > >
      > > MyIter& begin() {...; return *this;}
      > > MyIter& end() {...; return *this;}[/color]
      >
      > I think you're confused. "begin" and "end" should be members of
      > the container, not of the iterator.[/color]
      Thanks for your reply. Yes, I should put "begin" and "end" inside the
      container. However, it's something confusing me. Should I return a
      reference or just a value of the iterator? i.e Which one is better?

      MyIter& begin() {...; return *this;} // defined in MyContainer
      MyIter& operator++() {...; return *this;} // defined in MyIter

      or

      MyIter begin() {...; return *this;} // defined in MyContainer
      MyIter operator++() {...; return *this;} // defined in MyIter

      Should I have "const" here like

      MyIter& begin() const {...}

      Comment

      • Julián Albo

        #4
        Re: iterator design help

        Rex_chaos escribió:
        [color=blue]
        > MyIter begin() {...; return *this;} // defined in MyContainer
        > MyIter operator++() {...; return *this;} // defined in MyIter
        >
        > Should I have "const" here like
        >
        > MyIter& begin() const {...}[/color]

        You probably need:

        MyIter begin ()

        And

        MyConstIter begin () const

        Regards.

        Comment

        • Victor Bazarov

          #5
          Re: iterator design help

          "Rex_chaos" <rex_chaos@21cn .com> wrote in message
          news:f7a7417.03 10210956.27b4e8 84@posting.goog le.com...[color=blue][color=green][color=darkred]
          > > > template <typename ADT>
          > > > class MyIter
          > > > {
          > > > ...
          > > > MyContainer<ADT >& refc;
          > > > public:
          > > > MyIter(MyContai ner<ADT>& cont) :refc(a) {...}
          > > >
          > > > MyIter& begin() {...; return *this;}
          > > > MyIter& end() {...; return *this;}[/color]
          > >
          > > I think you're confused. "begin" and "end" should be members of
          > > the container, not of the iterator.[/color]
          > Thanks for your reply. Yes, I should put "begin" and "end" inside the
          > container. However, it's something confusing me. Should I return a
          > reference or just a value of the iterator? i.e Which one is better?[/color]

          How can you return a reference? A reference to what? Are you
          going to keep _the_only_ iterator in a container? What if I need
          two independent iterators? Just think about it for a minute.
          [color=blue]
          > MyIter& begin() {...; return *this;} // defined in MyContainer
          > MyIter& operator++() {...; return *this;} // defined in MyIter
          >
          > or
          >
          > MyIter begin() {...; return *this;} // defined in MyContainer
          > MyIter operator++() {...; return *this;} // defined in MyIter
          >
          > Should I have "const" here like
          >
          > MyIter& begin() const {...}[/color]

          Just like Julian suggested, you should have a special MyConstIter
          complementing MyIter.

          Get the Josuttis' book on the Standard library and read about
          iterators. It will be time well spent.

          Victor



          Comment

          Working...