我可以用别名模板为类模板进行特化吗?

14

这是一个简单的示例:

class bar {};

template <typename>
class foo {};

template <>
using foo<int> = bar;

这样做是允许的吗?


2
这与 typedef foo<int> bar; 有何不同? - Kerrek SB
3
这正好相反。这更像是typedef bar foo<int>;(虽然这是不被允许的)。在我的例子中,bar已经存在作为一种类型,而foo<int>成为它的一个新名称。(如果有帮助的话,您所写的相当于using bar = foo<int>;。) - R. Martinho Fernandes
哦,我明白了。但是你可能也会要求任何类定义都可以复制:class Foo = Bar;等等。我想这是不可能的... - Kerrek SB
using Foo = Bar;?(或者如果你更喜欢旧的风格,可以使用typedef Bar Foo;。)我不希望我的示例(如果有效)创建一个不同的类型(请让我知道是否我误解了你)。 - R. Martinho Fernandes
我写了几个宏定义,泛化了Aotium的答案,链接在这里https://dev59.com/Smw15IYBdhLWcg3wbLLU#14050604。 - alfC
显示剩余3条评论
3个回答

11

虽然无法直接特化别名,但是有一个解决方法。(我知道这是一个旧帖子,但它很有用。)

您可以创建一个具有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
你甚至可以通过继承一个自动提供typedef的远程类来进一步整理它。然而,有些人可能会觉得这更麻烦。个人而言,我喜欢它。
template <typename T>
struct remote
  { typedef T type; };

template <>
struct footype<float> :
  remote<bar> {};

foo<float> y; // y is a bar.

我一直在使用这个技巧,但是把它放在这里确实很有帮助。所以,感谢您的分享。欢迎来到StackOverflow! - R. Martinho Fernandes
在写了一个解决此限制的长答案后,我发现你的答案使用了相同的原则。无论如何,我又添加了一些define来使代码更短。如果你感兴趣,请看一下:https://dev59.com/Smw15IYBdhLWcg3wbLLU#14050604 - alfC
1
我认为您在using语句中漏掉了一个<T>template <typename T> using foo = typename footype<T>::type; - knedlsepp

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

参考资料: 14.1 [temp.decls]/p3:

3 因为别名声明不能声明一个模板ID,所以无法对别名模板进行部分或显式特化。


那是clang 3.0吗?好的,我从clang页面上看到我的clang 2.9不能工作。 - emsr

7
根据标准 §14.7.3/1(也在此 其他答案 中提到),别名不允许作为显式特化的一部分。
以下任何一个的显式特化: - 函数模板 - 类模板 - 类模板的成员函数 - 类模板的静态数据成员 - 类模板的成员类 - 类或类模板的成员类模板 - 类或类模板的成员函数模板
均可声明[...]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接