我有一个代码:
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()
?
答案 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,即使您的参数被标记为右值引用。您可以使用i
或std::move
std::forward
投回到左值
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; };
lambda(std::move(i));
}
int main() {
f(5);
}