我有一个代码:
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::movestd::forward
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; };
lambda(std::move(i));
}
int main() {
f(5);
}