traits help

From: Rex_chaos (rex_chaos_at_21cn.com)
Date: 10/23/03


Date: 23 Oct 2003 13:22:26 -0700

Hi there,
  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
    Iter(const Iter<T, non_const_iterator_tag>& it) :cont(it.c)
    {...}

  private:
    T *cont;
};

// Container is a container.

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 {...};
  private:
    T *data;
 ...
};

int main(void)
{
  Container<int> c;

  // copy constructor should be actived here
  Container<int>::const_iterator cit=c.begin();
  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.
Please help!

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?

Thanks in advance.



Relevant Pages

  • Re: Maintance of c++ code
    ... iterator constant in the standard, ... template ... template <class Iter_> ... container, some only work with particular containers. ...
    (comp.object)
  • Template member function cast bug in VC80SP1 (and more...)
    ... writing a small piece of metaprogramming code, we had to face some problems: ... and both MAP_BASE and MAP define 'iterator' as ... we'll omit template parameters from the text, ... template <typename S> ...
    (microsoft.public.vc.language)
  • iterator design help
    ... I am writing an iterator for a container. ... class MyIter ... While MyIter is applied to a template algorithm like std::transform, ...
    (comp.lang.cpp)
  • recursive template problem
    ... I have a little problem to design some template classes in a realizable way. ... I have some Container classes and some Proxy classes (proxies for ... // P is the Proxy class. ... template <typename T, typename P> ...
    (comp.lang.cpp)
  • Re: Template parameter that has a template argument list
    ... > container that holds a specific type. ... Of course, I am speaking of (template template) parameters, ... > void DoSomething(Iterator Begin, ...
    (alt.comp.lang.learn.c-cpp)