C ++标准
第14/2节:
在函数模板声明中, declarator-id 应为a 模板名称(即不是 模板id )。 [注意:在一个类中 模板声明,如果 declarator-id 是 template-id ,. 声明声明了一个类 模板部分专业化。
template-name
,template-id
和type-id
之间有什么区别?
以上引用是否意味着我们不能写出类似
的内容template <>
void templatefunction<int>(){ // ...}
还是我误解了这一点?
答案 0 :(得分:29)
template-name 是模板的名称。在您的示例中,templatefunction
是模板名称。
template-id 是带有模板参数列表的模板的名称。在您的示例中,templatefunction<int>
是 template-id 。 template-id 命名模板专业化。
type-id 命名一个类型。 template-id 是 type-id ; template-name 不是(因为它没有命名类型;它命名模板)。
您引用14/2的文字涉及模板声明,它声明了主要模板。您的示例不是模板声明,它是显式特化(14.7.3 / 1)。
答案 1 :(得分:6)
declarator-id是语法元素,它在simple-declaration(“type name;”)中指定名称。在下面的“A”和“B :: C”是声明者id
int A;
int B::C;
int A();
int *A;
int A[42];
template<typename T> void A();
type-id在语法上大致是一个简单的声明,其中缺少declarator-id。 type-id用作模板类型参数和强制转换中的语法元素。
int // type-id
int* // type-id
int[] // type-id
int() // type-id
int(*)() // type-id
template-name是模板的名称。从语法上讲,它出现在模板参数列表之前。上面的引用误用“template-name”和“declarator-id”,因为template-name是普通标识符,不包含任何限定符。 C ++ 0x已将文本更改为
在函数模板声明中,declarator-id的最后一个组件应该是template-name或operator-function-id(即,不是template-id)。
(最后一部分出现在诸如operator+()
之类的案例中)。甚至C ++ 0x文本也遗漏了一些案例 - 见this defect report。
“声明者身份”的滥用发生在说明中。该注释被C ++ 0x替换为
[注意:在类模板声明中,如果类名是......末尾注释]
在类模板声明中,语法指定的名称是类名而不是声明符。 class-name和declarator-id的关系如下(非常简化......)
class class-name { ... } declarator-id;
class foo { ... } bar;
在类模板声明中,可能没有指定声明符id。
template-id是模板名称,后跟模板参数列表。
引用意味着在函数 template 声明中,名称不能是template-id。在您的示例中,您声明了函数而不是模板。但是仍然存在显式特化声明模板的情况。但这只能发生在成员函数模板
上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() { }
答案 2 :(得分:2)
来自C++ Templates: The Complete Guide
David Vandevoorde,Nicolai M. Josuttis
8.3
显式模板参数:模板名称后面可以跟尖括号中的显式模板参数值。结果名称称为 template-id 。
例如:
template <typename T>
struct Demo{
// ...
};
int main()
{
Demo <int> d; // Demo is the template name, Demo<int> is the template-id
// ...
}
在函数模板声明中,declarator-id应为模板名称(即,不是template-id)。
例如(据我所知):
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
};
如果我错了,请有人纠正我。