Consider this code,
template<class T>
struct Sample
{
typename T::X *x; //declare pointer to T's X
};
In the above code, the keyword typename
is required by the compiler, so that it can disambiguate between nested types and nested values in templates. That means, in the absence of typename
keyword, compiler would interpret this as multiplication of T::X with x,
T::X *x; //multiply T::X with x
So in such situations where ambiguity can arise, the keyword typename
becomes necessity so as to remove ambiguities. But there are few situations when the context itself removes ambiguities. The other topic discusses contexts of base-class and function-parameters (the latter doesn't remove ambiguity though). In this topic, I particularly want to discuss other two contexts which seem to be unambiguous, but we're still required to write typename
,
typedef typename T::X xtype;
pX = new typename T::X;
In these two situations, the keywords typedef
and new
make it clear enough to the compiler that whatever follows is type, not value.
So my question is, why do compilers still need the typename
keyword, even in unambiguous situations such as when we use typedef
and new
?
EDIT (after reading this response from Johannes Schaub) :
//typedef NOT followed by a type!
int typedef A;
This syntax asks me to modify my question a little bit, so that the point which I'm trying to make, may be seen by others.
Consider this,
T::X typedef *x;
So from the context, it's still clear enough to the compiler that T::X is a type, no matter whether it appears before typedef
,or after typedef
. Unless C++ allows us to write typedef 5 five
or typedef T::value t_value
(where T::value is value), the presence of typedef
itself removes all ambiguities and so, typename
seems to be an unnecessary requirement by the Standard (in such situations). Same argument holds true for new
as well.
Also, I've written a class template which is using this struct as template argument:
struct A
{
struct X { string name; };
static const int X = 100;
};
I particularly want to know if the following code (from the constructor) is correct (portable) or not,
//two interesting statements
pX = new typename T::X; //T::X means struct X
product = T::X * p; //but here, T::X means int X
The complete code is here at ideone. Please have a look at it before replying. :-)
See Question&Answers more detail:
os