为什么模板定义中不允许使用结构?

时间:2010-03-25 23:18:35

标签: c++ templates

以下代码会产生错误error: ‘struct Foo’ is not a valid type for a template constant parameter

template <struct Foo>
struct Bar {

};

为什么会这样?

template <class Foo>
struct Bar {

};

完美无缺,甚至接受一个struct作为参数。

4 个答案:

答案 0 :(得分:9)

这只是语法规则的一个工件 - 语法只允许您使用classtypename关键字来指示类型模板参数。否则,参数必须是'非类型'模板参数(基本上是整数,指针或引用类型)。

我认为Stroustrup(以及他可能从中获取输入的任何其他人)决定不需要包含struct作为关键字来指示类型模板参数,因为不需要向后兼容C.

事实上,我的回忆(当我回到家时,我将不得不做一些读书)是当添加typename来表示模板类型参数时,Stroustrup本来希望为此目的使用class关键字带走(因为它令人困惑),但是依赖它的代码太多了。


编辑:

事实证明这个故事更像是(来自blog entry by Stan Lippman):

  

两个关键字的原因是   历史。在原始模板中   规范,Stroustrup重用了   现有的class关键字指定一个   类型参数而不是引入一个   可能当然会破坏的新关键字   现有的计划。不是那个   没有考虑新关键字 - 只是   它被认为是不必要的   鉴于其可能的中断。而且   直到ISO-C ++标准,这是   声明类型的唯一方法   参数。

     

似乎重复使用现有关键字   总是播下混乱。我们发现的是   初学者[想知道]   是否使用该类   约束或限制类型   用户可以指定的参数   类型而不是a   内置或指针类型。所以,那里   有些感觉没有   介绍了一个新的关键字是一个   错误。

     

在标准化过程中,确定   在一个。中发现了构造   解决的模板定义   表达虽然意思是   表示声明

     

...

     

委员会决定新的   关键字只是得到的门票   编译了它不幸的痴迷   用表达式。新关键字是   自描述的typename。

     

...

     

由于关键字位于工资核算上,   哎呀,为什么不解决引起的混乱   由最初的决定重用   class关键字。当然,鉴于   广泛的现有代码和   书籍和文章和谈话   他们使用class关键字发布帖子   选择也保留对此的支持   也可以使用关键字。所以那是   为什么你们两个都有。

答案 1 :(得分:4)

简短的回答是:template <class Foo>甚至接受uniondouble - 仍然不允许代替class。但是,typename是。这就是语法定义的方式。

更长的答案:当C ++的模板“发明”时,那个地方需要一个关键字,说下一个标识符是一个类型名称。决定重新使用现有的class关键字。这有点令人困惑,但是通常不愿意引入更多的关键字,因为它们总是会破坏一些现有的代码,当它不是关键字时会将其用作标识符。

稍后,typename因其他原因成为关键字,因为它更适合,现在可以在该地方使用template <typename Foo>。但是,由于在那个位置使用class的数十亿行代码,它必须保持有效。所以现在都允许。

正如C ++中常见的那样,这创建了几个关于在那个地方使用什么关键字的阵营。有些人坚持class,因为他们已经使用了十多年。其他人更喜欢typename,因为它更适合。有些人使用classFoo预计属于class类型(访问成员),typename也可以使用内置插件。

答案 2 :(得分:3)

您可以使用struct实例化模板;但是,声明模板类型的语法只允许关键字“class”或“typename”出现在您尝试使用关键字“struct”的位置。

我应该补充一点,你也可以使用特定的类型(例如int),如果你想根据编译时常量或基于具有外部链接的对象来实例化你的模板......但那是在某种程度上。

答案 3 :(得分:3)

因为模板参数的关键字是classtypename。这不会将Foo参数限制为类 - 它可以是任何类型。