> The name "vector<T>::iterator" is a dependent name because it depends on the template parameter
Yes.
> Because it's a dependent name the compiler doesn't recognize it, so whether
> vector<T>::iterator is a type or an object is ambiguous.
Because it's a dependent name (which is not part of the current instantiation
MyClass<T>), during phase one, without the
typename disambiguator, the compiler parses it as a non-type (this is the default).
> Can you show me the two ways that the compiler can interpret that line of code?
> One where it's a type and one where it's an object?
That is the point of Vandevoorde's proposal:
If X<T>::Y — where T is a template parameter — is to denote a type, it must be preceded by the keyword typename ; otherwise, it is assumed to denote a name producing an expression. There are currently two notable exceptions to this rule: base-specifiers and mem-initializer-ids.
...
Clearly, no typename is needed for this base-specifier because nothing but a type is possible in that context. However, there are several other places where we know only a type is possible and asking programmers to nonetheless specify the typename keyword feels like a waste of source code space (and is detrimental to readability). |
The
defining-type-id used in a
typedef declaration must be the name of a type.
However, there are many situations where the disambiguator is required.
For examplewhere
T is a template parameter, in the construct
T::dependent name(0),
the dependent name could be either the name of a type (eg. a nested class)
or the name of a non-type (eg. a static member function)