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

时间:2014-02-21 17:34:24

标签: c++ c++11 rvalue-reference pass-by-rvalue-reference

我有一个代码:

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

int main() {
  f(5);
}

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

为什么i在传递给int时将其类型更改为lambda()

3 个答案:

答案 0 :(得分:14)

i的类型为int&&,即类型为“int的右值引用”。但请注意,i本身是左值(因为它有一个名称)。并且作为左值,它不能绑定到“对rvalue的引用。”

要绑定它,您必须使用std::move()std::forward()将其转回右值。

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

答案 1 :(得分:6)

这里有两个要素:

  • 输入:参数i的类型为int&&,或“int的右值参考”,其中“rvalue reference”是{的名称{1}}功能,允许将 rvalues 绑定到引用;

  • 值类别:这是关键。 &&有一个名称,因此命名它的表达式是左值,无论其类型或标准委员会决定调用该类型的内容。 :)

(请注意,看起来像i表达式的类型为i,而不是int,因为原因。右值ref在丢失时丢失你开始使用这个参数,除非你使用int&&这样的东西来取回它。)

答案 2 :(得分:4)

i是一个名称,任何按名称访问的对象都自动为LValue,即使您的参数被标记为右值引用。您可以使用istd::move

std::forward投回到左值
void f(int&& i) {
  auto lambda = [](int&& j) { (void)j; };
  lambda(std::move(i));
}

int main() {
  f(5);
}