typename

S

saneman

In a template class I have:

typedef std::list<V,A> list;
typedef list::iterator iterator;

but this gives a compile error. If I replace the second line with:

typedef typename list::iterator iterator;

it works. But why? I have read that typename should be used when an
expression depends on template parameters.

If that is the case why is it not necessary to use typename in the first
line?
 
G

Gianni Mariani

saneman said:
In a template class I have:

typedef std::list<V,A> list;
typedef list::iterator iterator;

but this gives a compile error. If I replace the second line with:

typedef typename list::iterator iterator;

it works. But why? I have read that typename should be used when an
expression depends on template parameters.

If that is the case why is it not necessary to use typename in the first
line?

Because the first line is always a class and hence always a type so no
typename is required. In the second case. std::list<V,A> may be a
specialization and hence iterator could literally be anything so you're
telling the compiler that it really is a type. The reason you need to
do that is because the c++ grammer becomes ambiguous otherwise.
 
A

Alf P. Steinbach

* saneman:
In a template class I have:

typedef std::list<V,A> list;
typedef list::iterator iterator;

but this gives a compile error. If I replace the second line with:

typedef typename list::iterator iterator;

it works. But why? I have read that typename should be used when an
expression depends on template parameters.

If that is the case why is it not necessary to use typename in the first
line?

In the first line std::list<V,A> will be a concrete a concrete class
when the template parameters are filled in, and thus known to be a type.

It's unknown exactly /which/ concrete class std::list<V,A> will be, but
it's known that it will be some concrete class.

The second line is equivalent to

typedef std::list<V,A>::iterator iterator;

Here, due to the lack of knowledge of exactly which concrete class
std::list<V,A> will be, e.g. due to specialization of the std::list
template, it's unknown whether there will be an 'iterator' member and if
so, what kind of member it will be -- type, variable, function,
template, what?

You have to say what you assume and require that it will be.

In effect, by adding the word 'typename' you make a specialization of
std::list that doesn't have a type 'iterator', invalid.


Cheers & hth.,

- Alf
 
A

Andrey Tarasevich

saneman said:
In a template class I have:

typedef std::list<V,A> list;
typedef list::iterator iterator;

but this gives a compile error. If I replace the second line with:

typedef typename list::iterator iterator;

it works. But why? I have read that typename should be used when an
expression depends on template parameters.
...

You haven't provided enough context, but from what you said already I
can make an educated guess about either 'V' or 'A' (or both) being a
template parameter, not a concrete types. If that's true, then type
'list' is still a dependent type, not a concrete type, i.e. it depends
on the template parameters. Just because you have "hidden" that
dependency behind a typedef name doesn't really change anything. You
still need a 'typename' when referring to nested typenames.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top