转发引用不推导到右值引用 [重复]

Forwarding reference does not deduce to rvalue reference [duplicate]

提问人:Elucidase 提问时间:9/21/2023 更新时间:9/21/2023 访问量:53

问:

首先,这个问题已经被其他人问过了,看到这个和这个,但(我认为)他们都没有提供令人满意的答案。

根据 cppreference

在开始扣除之前,对 P 和 A 进行以下调整:

  1. 如果 P 不是引用类型, a) 如果 A 是数组类型,则 A 替换为从数组到指针转换中获得的指针类型; b) 否则,如果 A 是函数类型,则 A 替换为从函数到指针转换中获得的指针类型; c) 否则,如果 A 是 cv 限定类型,则忽略顶级 cv 限定符进行推导:
  2. 如果 P 是 cv 限定类型,则在扣除时将忽略顶级 cv 限定符。
  3. 如果 P 是引用类型,则引用类型用于推导。
  4. 如果 P 是对 cv 非限定模板参数的右值引用(所谓的转发引用),并且对应的函数调用参数是左值,则使用对 A 的左值引用类型代替 A 进行推导

在这些转换之后,如下所述的演绎过程(参见从类型中演绎一节)并试图找到这样的模板参数,使推导的 A(即上面列出的调整后的 P 和推导的模板参数的替换)与转换后的 A 相同,即上面列出的调整后的 A。

使用此规则,我们查看以下代码,并得出以下答案type_name

template<typename T>
void foo(T && t) {
    std::cout << type_name<T>();
}

int main() {
    int a = 1;
    foo(std::move(a)); // int, not int&&
}

根据规则 3,由于 P = 是引用类型,因此引用类型用于推导,即推导的 A 是 。T &&TT

A 是 的类型,它是 类型的右值。没有转换适用,因此转换后的 A 是 。std::move(a)int &&int &&

为了使推导的 A 与转换后的 A 相同,我们将得到 。T = int &&

但是上面的代码显示.这是cppreference的不准确,还是我的误解?T = int

c++ rvalue-reference 模板-argument-deduction forwarding-reference

评论

0赞 j6t 9/21/2023
我认为你说的类型是错误的.事实并非如此;表达式从不具有引用类型。它的类型是 ,但其类别是 xvalue。std::move(a)int&&int
0赞 Alan Birtles 9/21/2023
重读副本上的答案,不是 rvale 引用,而是,即您的函数推断为不Ttvoid foo(<int> && t)void foo(<T &&> t)
0赞 Elucidase 9/21/2023
我没有足够的声誉在那里发表评论以要求澄清。

答:

1赞 HolyBlackCat 9/21/2023 #1

表达式不能有引用类型,因此 的类型是 ,而不是 。std::move(a)intint &&