14.7.3 / 6说明如下:
如果模板,成员模板或类模板的成员明确专门化,那么 专业化应在首次使用该专业化之前宣布,该专业化将导致在发生此类使用的每个翻译单元中进行隐式实例化;无需诊断。如果程序没有提供显式特化的定义,并且特殊化的使用方式会导致隐式实例化或成员是虚拟成员函数,则程序格式错误,无需诊断。永远不会为声明但未定义的显式特化生成隐式实例化。
然后给出以下示例:
template<class T> struct A
{
enum E : T;
enum class S : T;
};
template<> enum A<int>::E : int { eint }; // OK
template<> enum class A<int>::S : int { sint }; // OK
template<class T> enum A<T>::E : T { eT };
template<class T> enum class A<T>::S : T { cT };
template<> enum A<char>::E : char { echar }; // ill-formed, A<char>::E was instantiated
// when A<char> was instantiated
template<> enum class A<char>::S : char { schar }; // OK
我没有关注它如何编译最后一行而不是它之前的那一行。我希望这两个示例都失败,因为A<char>::E
和A<char>::S
都是隐式实例化的。我注意到当我从主模板中的class
的枚举键中删除S
时,最后一行失败并显示与另一行相同的消息。为什么会这样?
答案 0 :(得分:3)
类模板的隐式实例化隐式实例化未作用域成员枚举的定义,但仅实例化作用域成员枚举的声明。
§14.7.1[temp.inst] / p1(强调补充):
类模板特化的隐式实例化导致 隐式实例化声明,但不是 定义,默认参数或例外规范 类成员函数,成员类,作用域成员 枚举,静态数据成员和成员模板;而且它 导致 unscoped的定义的隐式实例化 成员枚举和成员匿名联盟。