Pupkin
Pupkin

Reputation: 59

Simple type specifier is template parameter

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

Answers (1)

AVH
AVH

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

Related Questions