Re: traits help
From: Victor Bazarov (v.Abazarov_at_attAbi.com)
Date: 10/23/03
- Next message: Arthur J. O'Dwyer: "Re: approx 100 assorted computer/ math/other books"
- Previous message: Rex_chaos: "traits help"
- In reply to: Rex_chaos: "traits help"
- Next in thread: Rex_chaos: "Re: traits help"
- Reply: Rex_chaos: "Re: traits help"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Next message: Arthur J. O'Dwyer: "Re: approx 100 assorted computer/ math/other books"
- Previous message: Rex_chaos: "traits help"
- In reply to: Rex_chaos: "traits help"
- Next in thread: Rex_chaos: "Re: traits help"
- Reply: Rex_chaos: "Re: traits help"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|