g++ 3.4.5 接受此代码:
template <typename T> struct A
{
static const char* const str;
};
struct B {};
typedef A<B> C;
template<> const char* const C::str = "B";
// Equivalent to following?
// template<> const char* const A<B>::str = "B";
但我不确定它实际上是合法的 C++03。尤其,
[14.7p3] 在类模板、类模板的成员或类成员模板的显式特化声明中,显式特化的类的名称应为模板 ID。
这个要求是说在这个例子的最后必须使用非 typedef 版本吗?还是我误解了什么?
编辑:进一步的证据:缺陷报告 403表明将类型(在该上下文中,函数调用表达式的参数类型)说成是模板 ID是不正确的,因为模板 ID具有句法含义,而不是语义一。后来的标准草案在 3.4.2中使用了“类模板专业化”而不是“模板 ID ”。
这支持了这样的论点,即尽管A<B>
和C
表示相同的类型(并且具有相同或几乎相同的语义含义),但A<B>
它是一个模板 ID而C
不是,因为术语模板 ID将句法内容指代为一系列标记而不是这些标记的含义。