Reputation: 6162
Suppose I have the following definitions
template <class T>
class Sequence
{
}
E.g
Sequence<string>
might be an array of strings, similar to vector<string>
// Now define iterator template
template <class T>
class SequenceIterator
{
}
The idea here of course is to be able to create an iterator over some sequence E.g.
SequenceIterator< Sequence<string> > iter1;
SequenceIterator< Sequence<int> > iter2;
The question I now have is how to define the member function that would exist inside SequenceIterator and whose purpose is to return the next value in the sequence. Typically I would expect to write that as
bool Next(T1 & value); // If the iterator has not finished, set value to the next item
However, the SequenceIterator
has been passed in a templated name already, i.e, Sequence<string>
or Sequence<int>
So the question is, how do I generically refer to that underlying type (string
or int
) so that I can define the Next member function.
Thanks, David
Upvotes: 1
Views: 240
Reputation: 10695
There are three ways: change the definition of Sequence
to include
typedef T type;
or, change the template parameters for SequenceIterator
to explicitly recognize that Sequence
is a template itself
template< template < class > class Seq, class T >
class SequenceIterator< Seq< T > >
and while the instantiation of SequenceIterator
does not change, you can now access T
directly. Thirdly, you can use a container traits class that handles the type deduction for you. The third option provides the least coupling between Sequence
and SequenceIterator
, but, like Mark said, the standard containers tend to use the first method.
Upvotes: 2
Reputation: 96311
The standard library solves this by having typedefs within every container. In this case Sequence<T>
would have a typedef T value_type;
so you can then use Sequence<T>::value_type
to refer to that type.
Also, I would highly consider using operator++
and operator*
like the standard library so you don't confuse people with a non-standard-like iterator interface.
Upvotes: 2