模板名称和模板ID之间的差异

时间:2010-09-26 04:07:53

标签: c++ templates

C ++标准

  

第14/2节:

     

在函数模板声明中,    declarator-id 应为a   模板名称(即不是   模板id )。 [注意:在一个类中   模板声明,如果    declarator-id template-id ,.   声明声明了一个类   模板部分专业化。

template-nametemplate-idtype-id之间有什么区别?

以上引用是否意味着我们不能写出类似

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

还是我误解了这一点?

3 个答案:

答案 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

};

如果我错了,请有人纠正我。