Re: traits help

From: Victor Bazarov (v.Abazarov_at_attAbi.com)
Date: 10/23/03


Date: Thu, 23 Oct 2003 20:45:08 GMT


"Rex_chaos" <rex_chaos@21cn.com> wrote...
> I am learning template programming and there is a problem about
> traits. Now consider a container and an iterator. Here is the code
>
> // tag for const iterator and non-const iterator
> struct non_const_iterator_tag {};
> struct const_iterator_tag {};
>
> // traits
> template <typename T,
> typename tag=non_const_iterator_tag>
> struct Iter_traits
> {
> typedef random_access_iterator_tag iterator_category;
> typedef T value_type;
> typedef ptrdiff_t difference_type;
> typedef T* pointer;
> typedef T& reference;
> };
>
> // For const iterator ...
> template <typename T>
> struct Iter_traits<T, const_iterator_tag>
> {
> typedef random_access_iterator_tag iterator_category;
> typedef T value_type;
> typedef ptrdiff_t difference_type;
> typedef const T* pointer;
> typedef const T& reference;
> };
>
>
> //Iter is an iterator
>
> template <typename T, typename tag=non_const_iterator_tag>
> class Iter
> {
> typedef typename Iter_traits<T, tag>::value_type value_type;
> typedef typename Iter_traits<T, tag>::reference reference;
> public:
> Iter(T *c) :cont(c) {...}
>
> // copy constructor to shift the non-const iterator to const
> iterator

Why do you say "to shift the ..."? It's just a copy constructor.

> Iter(const Iter<T, non_const_iterator_tag>& it) :cont(it.c)
> {...}
>
> private:
> T *cont;
> };
>
> // Container is a container.

The comment above seems unnecessary. The class name is self-
documenting.

>
> template <typename T>
> class Container
> {
> ...
> public:
> typedef Iter<T> iterator;
> typedef Iter<T, const_iterator_tag> const_iterator;
>
> iterator begin() {...};
> const_iterator begin() const {...};
> iterator end() {...};
> const_iterator end() const {...};

Drop the semicolons after the closing curly braces. The code
looks dirty due to them.

> private:
> T *data;
> ...
> };
>
> int main(void)
> {
> Container<int> c;
>
> // copy constructor should be actived here
> Container<int>::const_iterator cit=c.begin();

Why should it? c.begin() returns 'Container<int>::iterator'.
You want to assign it to 'Container<int>::const_iterator'.
Those two are different types.

> return 0;
> }
>
> An error occurs while compliation.
>
> `int* Iter<int, non_const_iterator_tag>::cont' is private
>
> I don't know why. It seems that it's due to the copy constructor.

No. It's due to the fact that you don't have a constructor that
constructs a const_iterator from a "regular" iterator.

> Please help!

Define a parameterised constructor that would convert 'iterator'
into 'const_iterator'.

>
>
> BTW, if I define begin() outside the class. e.g.
>
> template <typename T>
> Container<T>::iterator Container<T>::begin(void)
> {
> ...
> }
>
> The compiler will give a warning:
> `typename Container<T>::iterator' is implicitly a typename
> mplicit typename is deprecated, please see the documentation for
> details
>
> Is that anything wrong? Should I do something to prevent that warning?

You should declare such function this way:

    template<typename T>
        typename
            Container<T>::iterator Container<T>::begin()
    {
        ...

Victor



Relevant Pages

  • Re: "NULL" iterator
    ... >>that a zero value not be a valid iterator value. ... > that it has a constructor taking some kind of a node pointer; ... > there's no guarantee that every iterator of every container in every STL ...
    (comp.lang.cpp)
  • Re: Reuseable iterators - which is better?
    ... string given to the constructor. ... unlike built-in types like string. ... raise StopIteration ... "Reuseable Iterator for looping over a sequence backwards" ...
    (comp.lang.python)
  • Re: assigning NULL to an iterator
    ... Any iterator can be constructed with a default constructor. ... With sufficient thrust, pigs fly just fine. ... land, and it could be dangerous sitting under them as they fly ...
    (microsoft.public.vc.stl)
  • Re: Two questions : manipulator and coping costructor
    ... That's not a copy constructor. ... It is an iterator into the list. ... you the thing stored in the list, which is: a pointer. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: A non-const std::set iterator
    ... > iterator target to be modified. ... One major problem is that your destructor may throw, as sync may throw. ... Also maybe provide a constructor Iteratorwhere 'it' ... For this, consider using smart references. ...
    (comp.lang.cpp)