为什么C++模板参数应该声明为类类型?
语法功能模板为什么C++模板参数应该声明为类类型?
template <**class** T, ...>
returntype functionname(arguments)
{
.....
.....
}
的我有两个问题吗?
- 为什么模板参数应被声明为一个类的类型?(即 与使用class关键字)
- 当我们宣布它作为一个类类型,那么什么东西编译器 会做什么?
根据标准,有两个关键字:class
和typename
。您可以在模板定义中使用它们中的任何一个。两者具有相同的含义:当您在模板定义中编写class
(或typename
)时,这意味着模板的用户必须将类型作为模板参数传递给模板;这并不意味着什么。如果它是一个函数模板,那么模板参数可能是从参数推导(在某些情况下)到该函数。
这是通常在template
参数中使用class
引起的混淆。
那class
事情跟班没有关系;它只是说模板接受一个类型模板参数(而不是整数模板参数),它可以是任何类型,不仅仅是类。
那么,他们为什么选择class
?因为他们必须使用在任何C++程序中肯定没有使用的关键字,并且或多或少“听起来不错”,并且class
没问题,因为它已经是C++中的保留关键字了。
请注意,class
还有一个替代方案:typename
关键字。他们完全相同,但我认为typename
更清晰,因为该名称只是说“以下是一种类型的争论”,而不会让你认为它必须是一个类。
为什么两种语法都允许?因为typename
关键字在语言后面(当他们发现有必要添加另一个关键字以消除模板中的某些声明)时,才会引入该关键字;然后,对“template
”参数声明也进行了“翻新”。保留了class
关键字的这种用法,以便与在此期间编写的程序/文档保持兼容。
- 这里我说的简单 “整体”,很明显,我的意思是在普通非类型模板参数(C++ 11,§14.1¶4)。
-
模板参数中的class和typename之间没有语义上的区别。
(C++ 11,§14。1¶2)
“一些角落案件”?嗯,也许我过度使用模板,我必须经常写'typedef typename TemplateParamClass :: nestedClass ShortName'。 – leftaroundabout 2012-04-22 14:06:07
@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被视为整数。
那么,**某些**标准类型。 – 2012-04-22 14:05:29
因为标准所以如此 – 2012-04-22 13:58:16
@VJovic:废话。标准没有说“模板参数应该被声明为一个类类型”,但它必须用'class' ***关键字***声明。另外,说“因为标准这么说”,根本无助于理解标准化过程中选择的理由。 – 2012-04-22 14:07:35