views:

92

answers:

2

Hi,

let's say I'm using a templated class with something simple like

template <class T> 
class MyClass

and I want to use elements from T's namespace, for example T could be string, and i wanted to use

T::const_iterator myIterator;

or something like that. How do I achieve that ? Probably it's not possible or very simple, but I'm not getting any idea.

Thanks for answers !

+10  A: 

By default if T is a template parameter like in your example, the T::some_member is assumed not to name a type. You have to explicitly specify that it is, by prefixing it with typename:

typename T::const_iterator myIterator;

This resolves some parsing problems like in the following example

// multiplication, or declaration of a pointer?
T::const_iterator * myIterator;

So that the compiler can parse this even before instantiating the template, you have to give it a hand and use typename, including in those cases where it wouldn't be ambiguous, like in the first case above. The Template FAQ has more insight into this.

Johannes Schaub - litb
Great answer, thanks !
Homer J. Simpson
There is one case when "typename" doesn't have to be used (and can't be) : derivation, eg template<class T> class A : T::const_iterator {};
Benoît
@Benoit, right. Good note.
Johannes Schaub - litb
+5  A: 

It is definitely possible.

template< typename T >
class Example
{
    void foo( const T& t )
    {
     typedef typename T::value_type Type;
     typedef typename T::const_iterator Iter;
     Iter begin = t.begin();
     Iter end = t.end();

     std::copy( begin, end, std::ostream_iterator<Type>(std::cout) );
    }
};

The key is the typename part of the typedef.

caspin
Thank you too, making it an extra type for the whole class context seems a good idea.
Homer J. Simpson