以下代码会产生错误error: ‘struct Foo’ is not a valid type for a template constant parameter:
template <struct Foo>
struct Bar {
};
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
template <class Foo>
struct Bar {
};
Run Code Online (Sandbox Code Playgroud)
工作得很好,甚至接受一个结构作为参数.
这只是语法规则的一个工件 - 语法只允许您使用class或typename关键字来指示类型模板参数.否则,参数必须是'非类型'模板参数(基本上是整数,指针或引用类型).
我认为Stroustrup(以及他可能从中获取输入的任何其他人)决定不需要包含structasa关键字来指示类型模板参数,因为不需要向后兼容C.
事实上,我的回忆(当我回到家时,我将不得不做一些书籍读取)是当typename添加指示模板类型参数时,Stroustrup会喜欢class为此目的使用关键字带走(因为它很混乱),但有太多的代码依赖它.
编辑:
事实证明这个故事更像是(来自Stan Lippman的博客文章):
这两个关键字的原因是历史性的.在原始模板规范中,Stroustrup重用现有的class关键字来指定类型参数,而不是引入可能会破坏现有程序的新关键字.这不是一个新的关键词没有被考虑 - 只是因为它可能被破坏而被认为是不必要的.直到ISO-C++标准,这是声明类型参数的唯一方法.
重复使用现有关键字似乎总是令人困惑.我们发现初学者[想知道]类的使用是否限制或限制用户可以指定为类型类型的类型参数,而不是内置或指针类型.所以,有一种感觉,没有引入新的关键字是一个错误.
在标准化期间,在模板定义中发现了某些构造,这些构造解析为表达式,尽管它们用于表示声明
...
该委员会决定,一个新的关键字只是让编译器摆脱对表达式的不幸痴迷的门票.new关键字是自描述的typename.
...
由于关键字在工资单上,所以,为什么不修复由原始决策重用class关键字引起的混乱.当然,考虑到大量现有代码,书籍和文章以及使用class关键字的讲座和发布,他们也选择同时保留对该关键字的使用的支持.所以这就是你们两个都有的原因.