类模板的非类、非函数成员的显式专用化

Explicit specialization of non-class, non-function members of a class template

本文关键字:专用 函数 成员      更新时间:2023-10-16

查看代码:

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
}

正如在不能重载函数中讨论的那样,第一个专业化是合法的,甚至可以在 MSVC 中使用。而enum的第二个专用化甚至不想编译,说"错误 C2988:无法识别的模板声明/定义"。

在我看来,C++正在为方法做出相对不合逻辑的例外。枚举只是一个例子。同样的事情可以应用于成员类、typedefs 等。

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

这是

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 提交了一个错误。有人可以测试最近的叮当声吗?

<小时 />

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

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

  • 函数模板
  • 类模板
  • 类模板的成员函数
  • 类模板的静态数据成员
  • 模板的成员类
  • 类或类模板
  • 的成员类模板
  • 的成员函数模板或类模板

可以通过template<>介绍的声明来声明

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

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

C++11 也有别名模板,类似于模板化的 typedef,但它们不能显式专用化。

<小时 />

只允许类和函数被专用化,然后允许这些模板封装其他东西(如enumtypedef)的政策在我看来似乎比允许直接专化enum更一致。但是,也许语言正朝着您喜欢的方向发展。