14

我对下面的模板行为感到困惑,它可以用空尖括号(没有参数的模板)很好地编译,因为在语法上,模板<>被保留以标记显式模板特化。

template <typename T> void add(T a, T b) { }
int main() {
    add<>(10, 3); // compiles fine since both parameters are of same data type
    add<>(10, 3.2); // Error: no matching function for call to add(int, double)
}

在上述情况下,模板参数真的是可选的吗?

4

3 回答 3

12

template<>保留用于标记显式模板特化。

它意味着不同的东西,取决于上下文。这里它的意思是“使用默认或推导的参数”,就像你简单地说add.

在第一种情况下,两个函数参数具有相同的类型,因此模板参数可以推导出为int

在第二种情况下,它们具有不同的类型,因此无法推断出模板参数。您必须指定您想要的,例如add<double>,转换一个函数参数以匹配另一个,或修改模板以分别对每种类型进行参数化。

在上述情况下,模板参数真的是可选的吗?

是的,如果它可以从参数类型中推断出来。

于 2013-12-05T11:23:10.980 回答
6

在第一种情况下,的,因为可以通过标准的规则来推断。第二,,因为他们不能——你必须写这样的东西:

add<float>(10, 3.2);
于 2013-12-05T11:20:59.490 回答
3

您有一个模板参数和两个不同类型的函数参数。模板参数推导需要匹配两个参数,但如果你提供一个 int 和一个 double,它就不起作用。原因是推导的参数必须完全匹配并且不考虑类型转换。

语法

add<double>(10, 3.2); 

将明确强制T等于double。在这种情况下,int常量10将转换为double

您还可以添加另一个重载

template <typename T, typename U> void add(T a, U b) { }

并可能通过要求限制使用 SFINAEis_convertible<T, U>

于 2013-12-05T11:21:11.217 回答