隐式实例化取决于范围或未范围的枚举

时间:2014-08-08 02:57:04

标签: c++ templates c++11 stl

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>::EA<char>::S都是隐式实例化的。我注意到当我从主模板中的class的枚举键中删除S时,最后一行失败并显示与另一行相同的消息。为什么会这样?

1 个答案:

答案 0 :(得分:3)

类模板的隐式实例化隐式实例化未作用域成员枚举的定义,但仅实例化作用域成员枚举的声明。

§14.7.1[temp.inst] / p1(强调补充):

  

类模板特化的隐式实例化导致   隐式实例化声明,但不是   定义,默认参数或例外规范   类成员函数,成员类,作用域成员   枚举,静态数据成员和成员模板;而且它   导致 unscoped的定义的隐式实例化   成员枚举和成员匿名联盟。