// Function declaration.
template <typename T1,
typename T2,
typename RT> RT max (T1 a, T2 b);
// Function call.
max <int,double,double> (4,4.2)
// Function call.
max <int> (4,4.2)
Run Code Online (Sandbox Code Playgroud)
一种情况可能是您需要指定返回类型.
还有其他需要手动指定参数类型的情况吗?
iam*_*ind 10
(1)当函数没有参数且仍然是template类型时,您可能必须明确指定参数
template<typename T>
void foo ()
{}
Run Code Online (Sandbox Code Playgroud)
用法:
foo<int>();
foo<A>();
Run Code Online (Sandbox Code Playgroud)
(2)你想区分价值和参考.
template<typename T>
void foo(T obj)
{}
Run Code Online (Sandbox Code Playgroud)
用法:
int i = 2;
foo(i); // pass by value
foo<int&>(i); // pass by reference
Run Code Online (Sandbox Code Playgroud)
(3)需要推导出另一种类型而不是自然类型.
template<typename T>
void foo(T& obj)
{}
Run Code Online (Sandbox Code Playgroud)
用法:
foo<double>(d); // otherwise it would have been foo<int>
foo<Base&>(o); // otherwise it would have been foo<Derived&>
Run Code Online (Sandbox Code Playgroud)
(4) 为单个模板参数提供了两种不同的参数类型
template<typename T>
void foo(T obj1, T obj2)
{}
Run Code Online (Sandbox Code Playgroud)
用法:
foo<double>(d,i); // Deduction finds both double and int for T
Run Code Online (Sandbox Code Playgroud)
如果函数模板参数出现在函数参数列表中,则无需指定模板参数.例如,
template<typename T>
void f(const T &t) {}
Run Code Online (Sandbox Code Playgroud)
这T是一个模板参数,它出现在函数参数列表中,即const T &t.因此,调用此函数时无需指定模板参数:
f(10); //ok
Run Code Online (Sandbox Code Playgroud)
由于类型的10是int,因此,编译器可以推断从它模板参数T,和T变int.
请注意,由于类型推导是使用函数参数的信息完成的,因此其称为模板参数推导.现在继续阅读.
如果模板参数未出现在函数参数列表中,则必须提供模板参数.例:
template<typename T>
void g(const int &i) {}
Run Code Online (Sandbox Code Playgroud)
注意事项g()不同于f().现在T没有出现在函数参数列表中.所以:
g(10); //error
g<double>(10); //ok
Run Code Online (Sandbox Code Playgroud)
请注意,如果函数模板也在返回类型上进行模板化,并且返回类型与出现在函数参数列表中的类型不同,那么您必须提供返回类型:
template<typename T>
T h(const T &t) {}
Run Code Online (Sandbox Code Playgroud)
由于返回类型T与函数参数相同,因此可以从函数参数中进行类型推导:
h(10); //ok - too obvious now
Run Code Online (Sandbox Code Playgroud)
但如果你这样:
template<typename R, typename T>
R m(const T &t) {}
Run Code Online (Sandbox Code Playgroud)
然后,
m(10); //error - only T can be deduced, not R
m<int>(10); //ok
Run Code Online (Sandbox Code Playgroud)
请注意,即使函数模板m已经模板化了两种类型:R并且T,我们在调用它时只提供了一种类型.也就是说,我们写的m<int>(10)是相反的m<int,int>(10).写下之后没有什么害处,但如果你不这样做,那就没关系.但有时候你要指定两者,即使T可以推导出一种类型.当类型参数的顺序不同时,如下所示:
template<typename T, typename R> //note the order : its swapped now!
R n(const T &t) {}
Run Code Online (Sandbox Code Playgroud)
现在,您要提供两种类型:
n(10); //error - R cannot be deduced!
n<int>(10); //error - R still cannot be deduced, since its the second argument!
n<int,int>(10); //ok
Run Code Online (Sandbox Code Playgroud)
这里新的东西是:类型参数的顺序也很重要.
无论如何,这只涵盖了基本概念.现在我建议你阅读一些关于模板的好书,学习关于类型演绎的所有高级内容.