【问题标题】:C++ - Passing rvalue references to function?C++ - 将右值引用传递给函数?
【发布时间】:2020-04-30 01:59:50
【问题描述】:

我无法理解右值引用的工作原理。我有以下代码:

void f(int&& i)
{}

int main()
{
    int i = 42;
    int&& r = std::move(i);

    f(r);

    return 0;
}

在这里,我收到以下编译器错误:

prog.cpp: In function ‘int main()’:
prog.cpp:46:7: error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’
     f(r);
       ^
prog.cpp:38:6: note:   initializing argument 1 of ‘void f(int&&)’
 void f(int&& i)
      ^

当我将r 明确声明为右值引用时,为什么编译器会认为我在传递左值?执行f(std::move(r)) 似乎可行,但我仍然不明白那里有什么不同。

这是因为在f(r) 调用中,r 被视为左值吗?如果有,std::move(r) 的类型是什么?

【问题讨论】:

标签: c++


【解决方案1】:

类型和value categories 是两个不同的东西。

(强调我的)

每个 C++ 表达式(带有操作数的运算符、文字、变量名等)都具有两个独立的属性:类型和值类别

作为命名变量,r 是一个左值,不能绑定到右值引用。

(强调我的)

以下表达式是左值表达式:

  • 变量、函数、模板参数对象(C++20 起)或数据成员的名称,与类型无关,例如std::cinstd::endl即使变量的类型是右值引用, 由其名称组成的表达式是左值表达式;

另一方面,std::move(r) 是一个xvalue,它是一种右值,可以绑定到右值引用。

以下表达式是 xvalue 表达式:

  • 函数调用或重载的运算符表达式,其返回类型为对对象的右值引用,例如std::move(x)

关于你的疑问,

这是因为在f(r) 调用中,r 被视为左值吗?如果有,std::move(r) 的类型是什么?

是的,r 是左值表达式,std::move(r) 是 xvalue(右值)表达式;甚至这两种类型都是右值引用,即int&&

【讨论】:

  • 有道理。有趣的是,在 C++ 中,像将事物传递给要使用的函数这样概念上简单的事情却如此复杂。
  • @Martin 这是相当 C++ 风格的思维... ;)
猜你喜欢
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 2018-09-09
  • 1970-01-01
相关资源
最近更新 更多