我可以用别名模板专门化一个类模板吗?

Can I specialize a class template with an alias template?

本文关键字:一个 别名 专门化 我可以      更新时间:2023-10-16

下面是一个简单的例子:

class bar {};
template <typename>
class foo {};
template <>
using foo<int> = bar;

允许吗?

$ clang++ -std=c++0x test.cpp
test.cpp:6:1: error: explicit specialization of alias templates is not permitted
template <>
^~~~~~~~~~~
1 error generated.

Reference: 14.1 [temp.decls]/p3:

因为别名声明不能声明模板id,所以它不是模板id可以部分地或显式地专门化别名模板。

虽然别名的直接专门化是不可能的,但这里有一个解决方法。(我知道这是一个旧的帖子,但它是一个有用的。)

可以用typedef成员创建一个模板结构体,并对该结构体进行专门化。然后,您可以创建一个引用typedef成员的别名。

template <typename T>
struct foobase {};
template <typename T>
struct footype
  { typedef foobase<T> type; };
struct bar {};
template <>
struct footype<int>
  { typedef bar type; };
template <typename T>
using foo = typename footype<T>::type;
foo<int> x; // x is a bar.

这允许通过专门化footype来间接专门化foo

您甚至可以通过继承自动提供类型定义的远程类来进一步整理它。然而,有些人可能会觉得这更麻烦。就我个人而言,我喜欢它。

template <typename T>
struct remote
  { typedef T type; };
template <>
struct footype<float> :
  remote<bar> {};
foo<float> y; // y is a bar.

根据标准§14.7.3/1,别名不允许作为显式专门化:(

下列任意项的显式专门化:

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

可以声明为[…]