我正在阅读C++ Templates: The Complete Guide,以及" 13.7功能模板的部分专业化"作者说:
要重载功能模板,它们的功能参数必须以某种实质方式不同。考虑函数模板R convert(T const&),其中R和T是模板参数。我们可能非常希望将此模板专门用于R = void,但这不能使用重载来完成。
可以使用函数模板重载完成,对吗?如:
#include <iostream>
template <typename T, typename R>
R convert(T const&) { std:: cout << "R convert(T const&)\n"; }
template <typename T>
void convert(T const&) { std:: cout << "void convert(T const&)\n"; }
int main()
{
convert(0);
}
DEMO,结果是:
void convert(T const&amp;)
作者的真正含义是什么?
答案 0 :(得分:3)
考虑一个类模板部分特化:
template<class U, class V> class T { };
template<class V> class T<void, V> { };
当您编写T<void, int>
时,将使用部分特化。
现在考虑一个功能模板:
template <typename R, typename T>
R convert(T const&) { return /* something */; }
请注意,R
和T
的顺序在上面的模板参数列表中交换。这可能就是这样一个模板的编写方式 - 编写convert<R>(something)
,显式指定目标类型,同时让编译器推导出源类型。
现在假设您希望convert<void>(something)
做一些与众不同的事情。你不能通过过载来做到这一点:
template <typename T>
void convert(T const&) { }
如果您编写convert(something)
- 之前的格式错误,它将转到您的新重载,因为编译器无法推断R
第一个模板。但是如果你写convert<void>(something)
甚至convert<void, T>(something)
,它仍会转到原始模板。更糟糕的是,像convert<int>(1)
这样的东西现在形成不良,因为它含糊不清。
换句话说,您不能使convert<void, T>(something)
使用与convert<int, T>(something)
不同的实现,而您可以使用类模板部分特化来执行此操作。