类模板的非类,非函数成员的显式特化

时间:2012-06-30 04:58:30

标签: c++

查看代码:

template <class x> struct Foo
{
    int getX(x *p) { return(0); }
    enum E12 { a };
};

template <> int Foo<int>::getX(int*)
{
    return(-15);
}

template <> enum Foo<int>::E12
{
    a, b, c
}

正如Cannot overload function中所讨论的那样,第一个专业化是合法的,甚至可以在MSVC中使用。虽然enum的第二个专门化甚至不想编译,但说“错误C2988:无法识别的模板声明/定义”。

在我看来,C ++正在为方法制造相对非逻辑的异常。 Enum只是一个例子。同样的事情可以应用于成员类,typedef等。

我很高兴有人会对此发表评论。

1 个答案:

答案 0 :(得分:1)

这是C ++ 11的一个非常模糊的新功能。向Microsoft提交一份错误报告,虽然它不太可能优先,因为几乎没有人知道这是允许的。正确的语法是

template <class x> struct Foo
{
    int getX(x *p) { return(0); }
    enum E12 { a };
};

template <> int Foo<int>::getX(int*)
{
    return(-15);
}

template <> enum Foo<int>::E12
{
    a, b, c
};

我和GCC一起filed a bug。有人可以测试最近的Clang吗?


在C ++ 03中,只有类和函数可以显式专用。从标准,C ++ 03 14.7.3 / 1:

  

以下任何一项的明确专业化:

     
      
  • 功能模板
  •   
  • 课程模板
  •   
  • 类模板的成员函数
  •   
  • 类模板的静态数据成员
  •   
  • 类模板的成员类
  •   
  • 类或类模板的成员类模板
  •   
  • 类或类模板的成员函数模板
  •   
     

可以由template<>

引入的声明声明

成员枚举不是这种情况。 (一般来说,enum类型在第一次声明时始终只定义一次。)

要获取模板enumtypedef,您可以将其包装在类模板中。在您的情况下,它将是Foo的成员类模板。这种结构称为元函数。

C ++ 11也有别名模板,它们类似于模板化的typedef,但它们不能明确专门化。


仅允许类和函数专用的策略,然后允许这些模板封装其他内容,如enumtypedef,似乎比允许直接专门化{{1}更加一致}}。但是,也许语言正朝着你的首选方向发展。