如果此代码无效,那就太好了。但它在概念上是合理的,GCC接受它,尽管 Comeau 没有:
template< typename > struct t;
template<> struct t< int > {} r; // Bad declarator! Don't pee on the carpet!
(编辑:上面的编译但r
似乎没有被声明到任何范围内,所以它基本上被忽略了。)
显式特化填充了模板和类之间的一种下层区域。由显式特化声明的类型一旦定义就完成了。从编译器的角度来看,它不是模板。如果它是一个参数化的模板,那么声明一个对象是不可能的。考虑§14/3:
在模板声明、显式特化或显式实例化中,声明中的 init-declarator-list 最多应包含一个声明符。当这样的声明用于声明类模板时,不允许使用任何声明符。
“用于声明类模板”是什么意思?显然,主模板声明了一个类模板。根据 §14.5.5/1(FDIS 编号),部分专业化也是如此:
类模板名称为 simple-template-id 的模板声明是 simple-template-id 中命名的类模板的部分特化。
但是,当涉及到显式特化时,标准是根据标记序列前面的声明来说话的template<>
。它看起来像一个模板,它命名了一个模板名称,但它似乎没有声明一个模板。
真正奇怪的是,§14/3 将声明符的数量限制为“最多一个”。函数模板声明、显式特化或实例化必须只有一个声明符。任何涉及类模板的声明都必须完全为零……除了显式特化,它似乎已经落入了裂缝。忠实地,海湾合作委员会拒绝允许
template<> struct t< int > {} r, s; // Offer valid one per specialization.
我倾向于同意 GCC 的解释,尽管它可能是胡说八道。不幸的是,它可能会抑制它检测丢失分号的能力。请让允许的声明符的数量完全为零!