Re: Why doesn't this code compile?
fungus wrote:
Old Wolf wrote:
The phrase "dependent name" refers to "iterator" (not T).
The meaning of the name "iterator" depends on T.
It could either be a typename, or the name of a variable; we
don't know yet.
Shouldn't the compiler be able to deduce that?
Not at the point where the template is defined, which is where you want
to do early syntax checking.
template <class Ty>
struct S
{
typedef int MyType;
};
int i = 3;
template <class Ty>
struct C
{
S<Ty>::MyType * i; // declaration of variable, or multiplication?
};
If S<Ty>::MyType names a type, then the marked statement defines a data
member named i. If it names a value, then the marked statement
multiplies two numbers and throws the result away (assuming operator*
isn't overloaded). At this point in the source code it looks like MyType
names a type, but wait:
template <> struct S<int>
{
int i;
};
C<int> ci;
This uses the specialization S<int>, and now the expression means
something completely different.
Using typename in the definition of C is required so that the compiler
can analyze the syntax of that definition at the point where it occurs.
Without that, i.e. if the compiler assumes that S<Ty>::MyType always
names a type, you get error messages when you try to use C<int> rather
than when you define C.