为什么C++模板参数应该声明为类类型?

为什么C++模板参数应该声明为类类型?

问题描述:

语法功能模板为什么C++模板参数应该声明为类类型?

template <**class** T, ...> 
    returntype functionname(arguments) 
    { 
      ..... 
      ..... 
    } 

的我有两个问题吗?

  1. 为什么模板参数应被声明为一个类的类型?(即 与使用class关键字)
  2. 当我们宣布它作为一个类类型,那么什么东西编译器 会做什么?
+2

因为标准所以如此 – 2012-04-22 13:58:16

+2

@VJovic:废话。标准没有说“模板参数应该被声明为一个类类型”,但它必须用'class' ***关键字***声明。另外,说“因为标准这么说”,根本无助于理解标准化过程中选择的理由。 – 2012-04-22 14:07:35

根据标准,有两个关键字:classtypename。您可以在模板定义中使用它们中的任何一个。两者具有相同的含义:当您在模板定义中编写class(或typename)时,这意味着模板的用户必须将类型作为模板参数传递给模板;这并不意味着什么。如果它是一个函数模板,那么模板参数可能是从参数推导(在某些情况下)到该函数。

这是通常在template参数中使用class引起的混淆。

class事情跟班没有关系;它只是说模板接受一个类型模板参数(而不是整数模板参数),它可以是任何类型,不仅仅是类。

那么,他们为什么选择class?因为他们必须使用在任何C++程序中肯定没有使用的关键字,并且或多或少“听起来不错”,并且class没问题,因为它已经是C++中的保留关键字了。

请注意,class还有一个替代方案:typename关键字。他们完全相同,但我认为typename更清晰,因为该名称只是说“以下是一种类型的争论”,而不会让你认为它必须是一个类。

为什么两种语法都允许?因为typename关键字在语言后面(当他们发现有必要添加另一个关键字以消除模板中的某些声明)时,才会引入该关键字;然后,对“template”参数声明也进行了“翻新”。保留了class关键字的这种用法,以便与在此期间编写的程序/文档保持兼容。


  1. 这里我说的简单 “整体”,很明显,我的意思是在普通非类型模板参数(C++ 11,§14.1¶4)。
  2. 模板参数中的class和typename之间没有语义上的区别。

    (C++ 11,§14。1¶2)

+0

“一些角落案件”?嗯,也许我过度使用模板,我必须经常写'typedef typename TemplateParamClass :: nestedClass ShortName'。 – leftaroundabout 2012-04-22 14:06:07

+0

@leftaroundabout:你说得对,说这是一个角落的案例实际上有点太多了,但是在学习模板时不会立即升高。不过,我改变了一下措辞。 – 2012-04-22 14:10:46

(1)为什么模板参数应被声明为一个类的类型?

不是真的完全。您也可以使用typename。 :)
更重要的是,您也可以将某些类型的const对象声明为参数。例如

template<int I> // <---- 'I' is not a class/typename 
class A { ... }; 
... 
A<3> obj; 

(2)当我们宣布它作为一个类类型,那么什么东西编译器 会做什么?

其实不多
但是,当你调用它的对象时,编译器检查类型实际上是一个类型名称。例如

template<class T> 
class A { ... }; // ok ... not much to check 
... 
A<int> obj1; // compiler checks if 'int' is a type ---> yes 
A<3> obj2; // compiler checks if '3' is a type ---> no 

因为这是语言定义告诉你使用的词。 'T类'在这里意味着'T是某种类型的名字',而不是'T是某个类的名字'。

我相信理由在于希望不添加另一个保留字。

但是,该语言最终还添加了另一个保留字:您可以等同地说'typename T'。

注意,您可以通过标准的类型template,不仅类:

template <class T, int N> class mysequence {..}; 

所以,class关键字这里告诉编译器把T作为类。 N被视为整数。

+0

那么,**某些**标准类型。 – 2012-04-22 14:05:29