10

我有一个代码:

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()

4

3 回答 3

15

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

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

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

于 2014-02-21T17:36:32.103 回答
7

这里有两个元素在起作用:

  • Type:参数i具有 type int&&,或“rvalue reference to int”,其中“rvalue reference”是&&特征的名称,允许将rvalues绑定到引用;

  • 价值类别:这是关键。i有一个名字,所以命名它的表达式是一个lvalue,不管它的类型或标准委员会决定叫什么类型。:)

(Note that the expression that looks like i has type int, not int&&, because reasons. The rvalue ref is lost when you start to use the parameter, unless you use something like std::move to get it back.)

于 2014-02-21T17:47:22.303 回答
4

i是一个名称,并且通过名称访问的任何对象都自动成为 LValue,即使您的参数被标记为右值引用。您可以使用或i转换回右值std::movestd::forward

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

int main() {
  f(5);
}
于 2014-02-21T17:38:43.340 回答