2

我有一个基本模板:

template <class X> void f(X x) {}

现在我已经看到了两种专门化它的方法:

template <> void f<>(int x) {}

或者:

template <> void f<int>(int x) {}

gcc 会同时吃掉这两种变体,但不能同时吃掉这两种变体。

这两个专业是一样的吗?专门模板时,何时需要在第二个 <> 中指定类型?

4

2 回答 2

2

两个专业是一样的。template<>总是专门化一个现有的模板,而不是声明一个新的签名。如果从专业化参数类型中推导可以确定里面的内容<>,那么您可以省略该部分。(如果有更多的模板重载,那么将这些东西排除在外可能是个坏主意。可能会不清楚哪个模板是专门化的。)

顺便说一句,专门化功能通常是个坏主意。重载解析将更喜欢非模板重载,并有效地隐藏您希望阻止的专业化。与其结合重载和专业化机制,不如坚持重载。

于 2013-07-09T06:40:53.987 回答
2

您的两个变体都执行相同的专业化。您还可以使用第三种变体

template <> void f(int x) {}

它还将专门用于X = int. 它相当于您的第二个变体。

变体 withf<>和 plainf依赖于模板参数推导,而f<int>变体显式指定模板参数。

<>当模板参数推导不可能时,您可能需要显式指定类型。在其他情况下,您不必这样做。

例如,如果您的函数参数列表不依赖于模板参数X,那么您别无选择,只能显式指定模板参数

template <typename X> void bar() {}

template <> void bar<int>() {}

以上编译。但是,如果您将专业化替换为

template <> void bar<>() {} 

它将无法编译,因为编译器无法推断出模板参数。

于 2013-07-09T06:46:23.737 回答