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?
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).
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() { }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With