Reputation: 59
According to ISO 14882:2011 § 14.6.2.1:
A type is dependent if it is — a template parameter,
And according to § ISO 14882:2011 14.6:
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
But
template <typename T> class U
{
typename T t; // ill-formed, i have an compilier error
};
Are "dependent name" and "name used in a template declaration or definition and that is dependent on a template-parameter" the same concept? I try to resolve my missunderstanding, since it looks as collision between assertions in standard(ISO 14882:2011 § 14.6.2.1) and example from standard T t;.
Upvotes: 1
Views: 170
Reputation: 11516
Your example code is ill-formed, because of ISO section 17.7.3 (http://eel.is/c++draft/temp.res#3): T
is not a nested name-specifier
.
Hence, there's no way T
can be anything else but the typename T
used as the template parameter. I.e. the compiler can't be mistaken, so you don't need to qualify it with the typename-specifier
.
An example of a dependent type where the typename-specifier
is required would be T::value_type
, because the actual type/value of value_type
depends on what T
is. In that case you have to help the compiler out:
template <typename T> class U {
using t = T; // OK
using u = T::value_type; // ill-formed: needs typename-specifier
using v = typename t::value_type; // OK: qualified with typename keyword
};
Let's say you have the following:
class foo {
constexpr static int value_type = 7;
}
class bar {
using value_type = int;
}
This is the reason the 2nd typedef line above is ill-formed: if T
is foo
then value_type
is not actually a type, but a constant with a very confusing name. If T
is bar
then all is well. But the compiler can't know this, so you have to help him out and assure him value_type
is in fact a type. That also means you will be greeted with a compile error if you ever try to compile U<foo>
.
Note: I used C++11 syntax for the typedefs, because I find it much more readable. The explanation above still holds if you use typedef
instead of using
.
Upvotes: 1