为什么我不能将rvalue-reference传递给C++ 11中的另一个函数?

aby*_*s.7 7 c++ rvalue-reference c++11 pass-by-rvalue-reference

我有一个代码:

void f(int&& i) {
  auto lambda = [](int&& j) { (void)j; }
  lambda(i);
}

int main() {
  f(5);
}
Run Code Online (Sandbox Code Playgroud)

Clang ++给出了一个错误: no known conversion from 'int' to 'int &&' for 1st argument

为什么在传递给iint时改变它的类型lambda()

Rei*_*ica 14

i是类型int&&,也就是说,它是"rvalue reference to int" 的类型.但请注意,i它本身是一个左值(因为它有一个名称).作为左值,它不能绑定到"对右值的引用".

要绑定它,必须使用std::move()或将其转回rvalue std::forward().

扩展一点:表达式的类型及其值类别(很大程度上)是独立的概念.该类型iint&&.该值类i是左值.

  • @Abyss是的,有.例如,查看`const char*p;`.`p`是指向常量字符的指针,但p本身是*不*常量.我发现在心理上将"rvalue reference"重写为"对rvalue的引用"很有帮助.初始化引用的表达式是rvalue,而不是引用本身. (3认同)
  • RValueness 不是变量的特征,而是表达式的特征。(好吧,除非在某些特定的模板 y 情况下)。在表达式 `lambda(i)` 中,“lambda”和“i”都是左值,因为它们有名字。在我的回答的表达式中,`lambda(std::move(i))` lambda 仍然是一个左值,i 仍然是一个左值,但 std::move(i) 是一个右值。 (2认同)

Lig*_*ica 6

这里有两个要素:

  • 类型:参数i具有类型int&&或"rvalue reference to int",其中"rvalue reference"是&&要素的名称,允许将rvalues绑定到引用;

  • 价值类别:这是关键.i有一个名称,因此命名它的表达式是左值,无论其类型或标准委员会决定称之为该类型.:)

(注意,看起来像的表达式i有类型int,而不是int&&因为原因.当你开始使用参数时,rvalue ref会丢失,除非你使用类似的东西std::move来取回它.)