开发者

Custom container with custom iterator doesn't work when container defined as const

More or less everything is in the topic.

when I have

func(my_cont& c)
{ c.begin() };

things works, but

func(const my_cont& c)
{ c.begin()开发者_Go百科 };

doesn't work, compiler claims that cant convert this to const my_cont<..>.... from my_cont<..>

What are the requirements for the container and my custom iterator to handle this?


Your container class should have two implementations of begin() and end() - one returning iterator and another returning const_iterator:

      iterator begin ();
const_iterator begin () const;
      iterator end ();
const_iterator end () const;

const_iterator cannot be used to modify the object that it points to.


You need to add a const begin(), something like this:

class my_cont
{
public:
    const_iterator begin() const;
};

You'll have to define a const_iterator type also.


Here is a good article on writing iterators:
http://www.aristeia.com/Papers/CUJ_June_2001.pdf

As most people have noted you need a const version of begin() and end() that returns a const_iterator.

What most people have forgotten is that an iterator should be able to implicitly convert into a const_iterator. Otherwise it is hard to get a const iterator from a non cost object (without a lot of nasty casts).

 my_cont   data;
 for(my_cont::const_iterator loop = data.begin(); loop != data.end(); ++loop)
 {
     /* STUFF */
 }

Note above: The above calls will actually call the non cost versions begin() and end(). But they are being assigned to a const_iterator. So your iterators must be convertible to const_iterator for the above code to work (Note: There is no implicit conversion from const_iterator to iterator. That should take an explicit const_cast as it is inherently dangerous).

class my_cont
{
    public:
    class iterator { /* STUFF */ }
    class const_iterator
    {
        public: const_iterator(iterator const& rhs);
        /* STUFF */
    }

    iterator       begin();
    iterator       end();

    const_iterator begin() const;
    const_iterator end()   const;
    /* STUFF*/ 
};


This is exactly the reason why STL implements cost_iterator for containers. Just check how is it implemented in STL, I'm not sure you can find any better solution.


You can only call const member functions on a const object (or volatile member functions on a volatile object). The compiler is telling that iterator my_cont::begin() const is missing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜