在模板类中定义的枚举上的嵌套类的部分专业化

时间:2018-07-15 09:58:43

标签: c++ enums language-lawyer partial-specialization

请参见以下代码:

template <class T>
struct X {
  enum class E { e0 };

  template <class U, E e>
  struct Y {};

  template <class U>
  struct Y<U, E::e0> {
    static int f() { return 0; }
  };
};

int main() {
  X<int>::Y<int, X<int>::E::e0>::f();
}

VC ++ 15.7.5生成错误消息:

1>  test.cpp
1>  some_directory\test.cpp(15): error C2039: 'f': is not a member of 'X<int>::Y<int,X<int>::E::e0>'
1>  some_directory\test.cpp(15): note: see declaration of 'X<int>::Y<int,X<int>::E::e0>'
1>  some_directory\test.cpp(15): error C3861: 'f': identifier not found

但是,GCC和Clang似乎接受了此代码。

哪个是正确的?

编辑

在较旧版本的VC ++上,会生成以下错误消息:

source_file.cpp(9): error C2754: 'X<T>::Y<U,>': a partial specialization cannot have a dependent non-type template parameter
source_file.cpp(12): note: see reference to class template instantiation 'X<T>' being compiled
source_file.cpp(16): error C2039: 'f': is not a member of 'X<int>::Y<int,X<int>::E::e0>'
source_file.cpp(16): error C3861: 'f': identifier not found

所以我认为VC ++拒绝编译的原因是enum class E是在模板类中定义的。实际上,如果我将enum class E移到X之外,该错误就会消失(在旧版本和最新的15.7.5中)。

这种情况是否真的是对依赖的非类型模板参数进行部分专业化的情况?

1 个答案:

答案 0 :(得分:4)

GCC和Clang是正确的接受它。这些都是根据[temp.class.spec]/5进行的,它也有一个支持的示例:

  

可以在任何范围内声明类模板部分专业化   其中可以定义相应的主模板   ([namespace.memdef],[class.mem],[temp.mem])。 [示例:

{
    "venue_id": "10",
    "min_attendance": "4500",
    "max_attendance": "4500",
    "venue_sum": "4500",
    "venue_name": "Stadiumi Loro Boriçi",
    "average": "4500",
    "capacity": "16000",
    "team_name": "Skënderbeu Korçe"
}
     

-示例]

MSVC的一种解决方法可能是尝试在名称空间范围内对成员模板进行专门化。


对于您的编辑,我想说MSVC仍然是错误的。相关标准语言为[temp.class.spec]/8

  

在类模板部分专业化的参数列表中,   适用以下限制:

     
      
  • 与专用非类型参数相对应的模板参数的类型不应依赖于   专业化。 [示例:

    {
        "venue_id": "10",
        "min_attendance": "300",
        "max_attendance": "6000",
        "venue_sum": "31600",
        "venue_name": "Stadiumi Loro Boriçi",
        "average": "1858.82",
        "capacity": "16000",
        "team_name": "Vllaznia Shkodër"
    } 
    
         

    -示例]

  •   

将其应用于{ "venue_id": "10", "min_attendance": "300", "max_attendance": "6000", "venue_sum": "31600", "venue_name": "Stadiumi Loro Boriçi", "average": "1858.82", "capacity": "16000", "team_name": "Vllaznia Shkodër" }, { "venue_id": "10", "min_attendance": "4500", "max_attendance": "4500", "venue_sum": "4500", "venue_name": "Stadiumi Loro Boriçi", "average": "4500", "capacity": "16000", "team_name": "Skënderbeu Korçe" } 中的示例:枚举的类型是否取决于<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <testsuite errors="0" failures="2" hostName="name" name="Reporter" tests="1" time="202.053" timeStamp="Sun Jul 15 07:38:13 UTC 2018"> <testcase classname="bla" name="fail1" time="105.704"> <failure message="failure1" type="">trace...</failure> <failure message="failure2" type="">trace2...</failure> </testcase> </testsuite> 的另一个模板参数?答案是不。当然,它取决于<?xml version="1.0" encoding="UTF-8" standalone="yes"?><testsuite errors="0" failures="2" hostName="name" name="Reporter" tests="1" time="202.053" timeStamp="Sun Jul 15 07:38:13 UTC 2018"> <testcase classname="bla" name="fail1" time="105.704"> <failure message= "failure1 failure2 failure3 ... .." type="">trace...</failure> </testcase> </testsuite> ,但这是另一个模板专业化。编写定义时,部分模板不是我们专门研究的模板。