template <typename T>
void fun1(T t) {}
template <typename T>
void fun2(T && t) {}
int i = 1;
fun1(i); // the deduced type of T is int
fun2(i); // the deduced type of T is int &
fun1(i)和fun2(i)中推导出的T类型分别是int
和int &
,任何人都可以解释编译器如何进行演绎的机制?
这个问题不是Type not deduced to be r-value reference: why not?的副本,因为:
后来的问题解释了以下的扣除规则:
template <class T>
void foo(T&& )
在这里,我想知道扣除规则的区别
template <class T>
void foo(T&& )
和
template <class T>
void foo(T )
这是一个完美的前锋,可以根据提供给模板的参数产生不同的结果。
完美转发减少了对重载功能的需求,有助于避免转发问题。当您编写以引用作为参数并将这些参数传递(或转发)到另一个函数的泛型函数时,可能会发生转发问题。例如,如果泛型函数采用const T&类型的参数,则被调用函数不能修改该参数的值。如果泛型函数采用类型为T&的参数,则无法使用rvalue(例如临时对象或整数文字)调用该函数。
通常,要解决此问题,必须提供通用函数的重载版本,该函数同时为每个参数提供T&和const T&。结果,重载函数的数量随参数的数量呈指数增加。 Rvalue引用使您能够编写一个接受任意参数的函数版本,并将它们转发到另一个函数,就像直接调用另一个函数一样。
转发引用转发引用是一种特殊的引用,它保留函数参数的值类别,从而可以通过std :: forward转发它。转发参考是:
这是怎么回事:Template Deduction
因为i
的类型是int
,而不是int&
。正如[temp.deduct.call] paragraph 1所说
模板参数推导是通过将包含参与模板参数推导的模板参数的每个函数模板参数类型(称为P)与调用的相应参数的类型(称为A)进行比较来完成的,如下所述。
而[temp.deduct.call] paragraph 4说
通常,演绎过程试图找到模板参数值,这些参数值将使推导出的A与A相同(在如上所述变换类型A之后)。
转发参考案例是一种特殊情况。正如[temp.deduct.call] paragraph 3明确指出的那样
如果P是转发引用且参数是左值,则使用类型“对A的左值引用”代替A来进行类型推导。