tags:

views:

144

answers:

3

C++ Standard

Section 14/2 :

In a function template declaration, the declarator-id shall be a template-name (i.e., not a template-id). [Note: in a class template declaration, if the declarator-id is a template-id, the declaration declares a class template partial specialization.

What is the difference between a template-name, template-id and a type-id?

Does the above quote mean we cannot write something like

template <>
void templatefunction<int>(){ // ...} 

or have I misunderstood the point?

+12  A: 

The template-name is the name of the template. In your example, templatefunction is a template-name.

The template-id is the name of the template with the template arguments list. In your example, templatefunction<int> is the template-id. A template-id names a template specialization.

A type-id names a type. A template-id is a type-id; a template-name is not (because it does not name a type; it names a template).

The text you cite from 14/2 concerns a template-declaration, which declares a primary template. Your example is not a template-declaration, it is an explicit-specialization (14.7.3/1).

James McNellis
+2  A: 

From C++ Templates: The Complete Guide By David Vandevoorde, Nicolai M. Josuttis

8.3

Explicit template arguments: A template name can be followed by explicit template argument values enclosed in angle brackets. The resulting name is called a template-id.

For example:

template <typename T>
struct Demo{ 
    // ... 
};

int main()
{
   Demo <int> d; // Demo is the template name, Demo<int> is the template-id
   // ...
}

In a function template declaration, the declarator-id shall be a template-name (i.e., not a template-id).

For example (from what I have understood):

class A {
public:
    template <typename T> void f(T);
    template <typename T> struct X { };
};
class B : public A {
public:
    using A::f;     // fine
    using A::X      // fine

};
class C : public A {
public:
    using A::f<int>;     // ill formed, declarator-id shall not be a template id
    using A::X<double>   // ill formed, declarator-id shall not be a template id

};

Someone please correct me if I am wrong.

Prasoon Saurav
+3  A: 

A declarator-id is the syntactical element that specifies the name in a simple-declaration ("type name;"). In the following "A" and "B::C" is the declarator-id

int A;
int B::C;
int A();
int *A;
int A[42];
template<typename T> void A();

A type-id syntactically is roughly a simple-declaration where the declarator-id is missing. A type-id is used as the syntactical element in a template type argument and in a cast.

int // type-id
int* // type-id
int[] // type-id
int() // type-id
int(*)() // type-id

A template-name is the name of a template. Syntactically it appears before a template-argument list. The above quote misuses "template-name" and "declarator-id", because a template-name is a plain identifier and does not contain any qualifiers. C++0x has changed the text to

In a function template declaration, the last component of the declarator-id shall be a template-name or operator-function-id (i.e., not a template-id).

(The last part appears in cases such as operator+()). Even the C++0x text misses some cases - see this defect report.

The misuse of "declarator-id" happens in the note. The note was replaced by C++0x with

[ Note: in a class template declaration, if the class name is a ... — end note ]

In class template declarations, the name specified syntactically is a class-name instead of a declarator-id. The relation of class-name and declarator-id is as follows (very simplified...)

class class-name { ... } declarator-id;
class foo        { ... } bar;

In class template declarations, there may not be a declarator-id specified.


A template-id is a template-name followed by a template-argument list.


The quote means that in a function template declaration, the name must not be a template-id. In your example you declare a function instead of a template. There are still cases where an explicit specialization declares a template, though. But that can only happen for member function templates

template<typename T>
struct A {
  template<typename U>
  void f();
};

// this explicit specialization *contains* a template declaration and
// declares an identifier (a template-name) qualified by A<int>:: 
template<> template<typename U> 
void A<int>::f() { }
Johannes Schaub - litb