C++中template<>空尖括号的含义是什么?

53
template<>
class A{
//some class data
};
我经常看到这类代码。上述代码中的template<>有什么用?在哪些情况下需要强制使用它?

2
哦...在发帖之前我尝试使用"template<>"在谷歌上搜索,但没有得到好的结果。感谢您提供正确的搜索关键词。但我认为Stack Overflow上可能有更好的答案。 - Vijay
3个回答

80

template<>告诉编译器后面是一个模板特化,具体来说是完全特化。通常,class A应该像这样:

template<class T>
class A{
  // general implementation
};

template<>
class A<int>{
  // special implementation for ints
};

现在,每当使用A<int>时,都会使用专门化的版本。您还可以使用它来专门化函数:
template<class T>
void foo(T t){
  // general
}

template<>
void foo<int>(int i){
  // for ints
}

// doesn't actually need the <int>
// as the specialization can be deduced from the parameter type
template<>
void foo(int i){
  // also valid
}

通常情况下,您不应该专门化函数,因为简单的重载通常被认为更优秀
void foo(int i){
  // better
}

现在,为了更加完整,以下是部分特化:

template<class T1, class T2>
class B{
};

template<class T1>
class B<T1, int>{
};

这个模板和完整的特化模板一样,只是当第二个模板参数是int时,就会使用特殊版本(例如:B<bool,int>B<YourType,int>等)。


2
+1 好答案!也许你应该补充说明这是一个完整的模板特化。尽管只有一个模板参数,但无论如何都不可能进行部分特化。 - Christian
这对于定义类型特性也非常有用。 - StackedCrooked
@Xeo:我希望那些给负评的人能够留下评论,无论是匿名的还是不是(或者至少第一个留言者)。 - Matthieu M.
@Xeo:增加“为什么需要完全模板特化”可能是有意义的。我认为唯一有用的场景是模板元编程。有人有更多的见解吗? - Jaywalker
@Jaywalker:你是指特别针对函数还是结构体/类? - Xeo

9

template<> 引入模板的完全特化。你提供的例子本身实际上不是有效的;在变得有用之前,你需要一个更详细的场景:

template <typename T>
class A
{
    // body for the general case
};

template <>
class A<bool>
{
    // body that only applies for T = bool
};

int main()
{
    // ...
    A<int>  ai; // uses the first class definition
    A<bool> ab; // uses the second class definition
    // ...
}

这看起来很奇怪,因为它是更强大的“部分特化”功能的一个特殊案例。


显式(而非“总体”)特化不是部分特化的特例。显式特化定义了一个由模板ID标识的类;而部分特化则定义了通过主模板访问的新模板。 - Potatoswatter
1
我更喜欢使用术语“total”,因为它与“partial”(这是一件事)相对立,而“explicit”则与“implicit”(这不是一件事)相对立。我知道这不是标准术语。从句法上讲,即使最符合标准的方法是区分类和类模板,显式特化也是部分特化的一种特殊情况。 - John Calsbeek

7
看起来不太对。你可能应该这样写:
template<>
class A<foo> {
// some stuff
};

...这将是类型foo的模板特化


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