转发引用不会推导出右值引用

问题描述 投票:0回答:1

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

根据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 =

T &&
是引用类型,因此使用引用类型
T
进行推导,即推导出A
T

A

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

为了使推导的 A 与变换后的 A 相同,我们将有

T = int &&

但是上面的代码显示了

T = int
。这是 cppreference 的不准确,还是我的误解?

c++ rvalue-reference template-argument-deduction forwarding-reference
1个回答
0
投票

表达式不能有引用类型,因此

std::move(a)
的类型是
int
,而不是
int &&

© www.soinside.com 2019 - 2024. All rights reserved.