在哪些情况下,需要具体指定模板的参数`types`?

Aqu*_*irl 7 c++ templates

// 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)


Naw*_*waz 8

如果函数模板参数出现在函数参数列表中,则无需指定模板参数.例如,

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)

由于类型10int,因此,编译器可以推断从它模板参数T,和Tint.

请注意,由于类型推导是使用函数参数的信息完成的,因此其称为模板参数推导.现在继续阅读.

如果模板参数未出现在函数参数列表中,则必须提供模板参数.例:

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)

这里新的东西是:类型参数的顺序也很重要.

无论如何,这只涵盖了基本概念.现在我建议你阅读一些关于模板的好书,学习关于类型演绎的所有高级内容.