关于右值引用的困惑:它的类型是什么?
我在这里有一个非常简单的 func 定义:
void testRvalue(int&& r)
{
printf("rvalue ref is calledn");
testRvalue(r); // this line gives "no known conversion from 'int' to 'int &&' for 1st argument"
}
我的意思是......在这个函数中,什么是类型r?是不是它int&&(该参数是int&& r那么怎么来r的类型是不是int&&?)如果是这样,为什么我不能通过这r本FUNC本身,这需要一个int&&类型作为参数?
究竟是什么类型r?int&&或者int?如果int,为什么???
回答
一个很好的读物是Value Categories。
是的,变量的类型r确实是int&&。然而,这里重要的是表达式和:
每个 C++ 表达式(带有操作数的运算符、文字、变量名称等)都具有两个独立的属性:类型和值类别。每个表达式都有一些非引用类型,每个表达式都属于三个主要值类别之一:纯右值、xvalue 和左值。
表达式r是一个左值:
左值
以下表达式是左值表达式:
- 变量的名称 [...],与类型无关。即使变量的类型是右值引用,由其名称组成的表达式也是左值表达式;
右值引用可以绑定到 prvalues 或 xvalue 但不能绑定到左值,所以如果你想绑定一个右值引用,r你需要转换r为 xvalue。这是完成的std::move,尽管它的名字只是一个演员。
你可以很容易地这样推理:如果它有一个名字,那么它就是一个左值(即使那个 id 的类型是右值引用)。您不能将右值引用(原则上应该绑定到临时对象)绑定到具有名称的内容。有名字的东西可以重复使用。你需要std::move以使移动从左值。
关于“没有已知的来自‘int’的转换”的消息。如上所示,表达式的类型r是int,但是更合适的诊断消息应该是这样的:“右值引用不能绑定到左值”。
事实上,较新的 clang 和 gcc 给出了更好的信息:
海湾合作委员会
错误:无法将“int&&”类型的右值引用绑定到“int”类型的左值
铛
候选函数不可行:第一个参数需要右值