为什么推断出有趣的(T t)和有趣(T& t)类型在C ++中是不同的?

时间:2018-01-17 15:22:59

标签: c++ rvalue-reference

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类型分别是intint &,任何人都可以解释编译器如何进行演绎的机制吗?

更新

此问题与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 )

2 个答案:

答案 0 :(得分:0)

这是完美的前锋,可以根据提供给模板的参数产生不同的结果。

  

完美转发减少了对重载功能的需求并提供帮助   避免转发问题。转发问题可能发生在   你编写了一个以引用作为参数的泛型函数   它将这些参数传递(或转发)到另一个函数。对于   例如,如果泛型函数采用const T&amp;类型的参数,   那么被调用的函数不能修改该参数的值。如果   泛型函数采用类型为T&amp;的参数,然后是函数   无法通过使用右值(例如临时对象或)来调用   整数字面。)

     

通常,要解决此问题,必须提供重载   通用功能的版本,兼顾T&amp;和const T&amp;对于   它的每个参数。结果,重载的次数   函数随参数的数量呈指数增长。   Rvalue引用使您可以编写一个函数版本   接受任意参数并将它们转发给另一个函数   如果直接调用了其他函数。

Rvalue Reference

  

转发参考资料   转发引用是一种特殊的引用,它保留了函数参数的值类别,从而可以通过std :: forward转发它。转发参考是:

  1. 函数模板的函数参数,声明为对同一函数模板的cv-unqualified type模板参数的rvalue引用:
  2. 自动&安培;&安培;除非从括号括起的初始化列表中推断出来。
  3. Forwarding Reference

    这是怎么回事这里解释: Template Deduction

答案 1 :(得分:0)

因为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来进行类型扣除。