繁体   English   中英

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

[英]Why are structs not allowed in template definitions?

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

template <struct Foo>
struct Bar {

};

为什么会这样?

template <class Foo>
struct Bar {

};

工作得很好,甚至接受一个结构作为参数。

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

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

事实上,我的回忆 (当我回到家时我必须做一些书读) 是当添加typename以指示模板类型参数时,Stroustrup会喜欢为此目的使用class关键字带走(因为它令人困惑),但有太多的代码依赖它。


编辑:

事实证明这个故事更像是(来自Stan Lippman博客文章 ):

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

重复使用现有关键字似乎总是令人困惑。 我们发现初学者[想知道]类的使用是否限制或限制用户可以指定为类型类型的类型参数,而不是内置或指针类型。 所以,有一种感觉,没有引入新的关键字是一个错误。

在标准化期间,在模板定义中发现了某些构造,这些构造解析为表达式,尽管它们用于表示声明

...

该委员会决定,一个新的关键字只是让编译器摆脱对表达式的不幸痴迷的门票。 new关键字是自描述的typename。

...

由于关键字在工资单上,所以,为什么不修复由原始决策重用class关键字引起的混乱。 当然,考虑到大量现有代码,书籍和文章以及使用class关键字的讲座和发布,他们也选择同时保留对该关键字的使用的支持。 所以这就是你们两个都有的原因。

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

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

之后,由于其他原因, typename成为关键字,因为它更适合,现在可以在那个地方使用: template <typename Foo> 然而,随着数十亿的代码中使用了有行class在那个地方,它必须保持有效用于这一目的。 所以现在都允许。

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

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

我应该补充一点,你也可以使用特定的类型(例如int ),如果你想基于编译时常量或基于具有外部链接的对象来实例化你的模板......但这有点偏僻。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM