C++ 为什么模板定义中不允许使用结构?
以下代码产生错误:'struct Foo'不是模板常量参数的有效类型:C++ 为什么模板定义中不允许使用结构?,c++,templates,C++,Templates,以下代码产生错误:'struct Foo'不是模板常量参数的有效类型: template <struct Foo> struct Bar { }; 模板 结构条{ }; 为什么会这样 template <class Foo> struct Bar { }; 模板 结构条{ }; 工作非常好,甚至可以接受结构作为参数。您可以使用结构实例化模板;但是,用于声明模板类型的语法仅允许在尝试使用关键字“struct”的位置显示关键字“class”或“typename”
template <struct Foo>
struct Bar {
};
模板
结构条{
};
为什么会这样
template <class Foo>
struct Bar {
};
模板
结构条{
};
工作非常好,甚至可以接受结构作为参数。您可以使用结构实例化模板;但是,用于声明模板类型的语法仅允许在尝试使用关键字“struct”的位置显示关键字“class”或“typename”
我应该补充一点,如果您想基于编译时常量或具有外部链接的对象实例化模板,您还可以使用特定类型(例如,
int
)。。。但这有点像旁白。因为模板参数的关键字是class
或typename
。这并没有将Foo参数限制为类-它可以是任何类型。这只是语法规则的产物-语法只允许您使用类
或类型名
关键字来指示类型模板参数。否则,参数必须是“非类型”模板参数(基本上是整数、指针或引用类型)
我想Stroustrup(以及他可能从中获取输入的其他人)决定不需要将struct
作为一个关键字来指示类型模板参数,因为不需要与C向后兼容
事实上,我的记忆(我回家后必须读一些书)是,当添加typename
以指示模板类型参数时,Stroustrup本想取消使用class
关键字来表示模板类型参数(因为它令人困惑),但依赖它的代码太多了
编辑: 事实证明,这个故事更像是(来自a): 这两个关键字的原因是 历史的在原始模板中 规范,Stroustrup重用了 现有类关键字以指定 输入参数,而不是引入 新的关键字,当然可能会打破 现有计划。那不是一个好主意 没有考虑新的关键字--只是 这被认为是没有必要的 鉴于其潜在的破坏性。向上 在ISO-C++标准之前,这是 声明类型的唯一方法 参数 对现有关键字的重用似乎是可行的 总是制造混乱。我们发现的是 那些初学者[好奇] 是否使用该类 约束或限制类型 用户可以指定的参数 类类型,而不是 内置或指针类型。好了 是不是觉得没有 引入了一个新的关键字 错误 在标准化过程中,某些 构造是在一个 解析为的模板定义 表达,尽管他们是有意的 表明声明 委员会决定设立一个新的委员会 关键字只是获得 他摆脱了不幸的困扰 带着表情。新的关键字是 自我描述的类型名 因为关键字在工资单上, 见鬼,为什么不纠正引起的混乱呢 根据最初的决定,重新使用 类关键字。当然,考虑到 大量的现有代码和 书籍、文章、谈话和 使用class关键字的帖子,它们 也选择保留对此的支持 关键字的使用。那就是 为什么你们两个都有
简短的回答是:
模板
甚至接受一个联合
或一个双重
——但是,这两个都是不允许的,而不是类
。但是,typename
是。这就是语法的定义方式
稍长的答案:当C++的模板在哪里被“发明”时,在那个地方需要一个关键字,说明下一个标识符是一个类型名称。决定重新使用现有的
类
关键字。这有点让人困惑,但人们普遍不愿意引入更多的关键字,因为它们总是破坏一些现有的代码,这些代码在不是关键字时将其用作标识符
后来,由于其他原因,typename
成为了一个关键字,而且由于它更适合,现在可以在那个地方使用它:template
。然而,在那里有数十亿行代码在使用class
,因此它必须保持有效。所以现在两者都被允许了
在C++中常见,这就创建了几个用于在那个地方使用关键字的阵营。有些人坚持使用
类
,因为他们已经使用了十多年。其他人更喜欢typename
,因为它更适合。当Foo
预计为class
类型(可访问成员)时,有些人使用class
,当可以使用内置时,也使用typename
据我记忆所及,我一直在使用模板
,我相信类
部分会让人们误以为它是实际的类
,并且出于某种奇怪的原因想将结构
粘贴在其中……至少在他的C++0x FAQ()中,Stroustrup似乎以完全任意的方式使用typename
和class
。很可能没有办法避免“混乱”,因为迟早你会遇到使用<代码>类< /> >的代码(这只是在一般的模板代码,IMO中键入较少),你必须知道没有任何区别。因为C++语言定义了它,无论是class
还是typename
,在我看来typename
更能描述正在发生的事情,否则,出于未知原因,ppl会尝试用struct
替换它<代码>模板表示存在一个类型
t