函数模板重载(不同的返回值类型)

时间:2014-07-27 07:38:49

标签: c++ templates

我正在阅读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;)

作者的真正含义是什么?

1 个答案:

答案 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 */; } 

请注意,RT的顺序在上面的模板参数列表中交换。这可能就是这样一个模板的编写方式 - 编写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)不同的实现,而您可以使用类模板部分特化来执行此操作。