我有一个代码:
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()
?
我有一个代码:
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()
?
i
是 类型int&&
,也就是说,它的类型是“对 . 的右值引用int
”。但是,请注意它i
本身是一个左值(因为它有一个名称)。作为左值,它不能绑定到“对右值的引用”。
std::move()
要绑定它,您必须使用or将其转回右值std::forward()
。
稍微扩展一下:表达式的类型及其值类别(很大程度上)是独立的概念。的类型是。i
_ int&&
的值类别是i
左值。
这里有两个元素在起作用:
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.)
i
是一个名称,并且通过名称访问的任何对象都自动成为 LValue,即使您的参数被标记为右值引用。您可以使用或i
转换回右值std::move
std::forward
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; };
lambda(std::move(i));
}
int main() {
f(5);
}