函数中右值引用参数的类型是什么?
What is the type of an rvalue reference parameter inside a function?
我这里有一个非常简单的函数定义:
void testRvalue(int&& r)
{
printf("rvalue ref is called\n");
testRvalue(r); // this line gives "no known conversion from 'int' to 'int &&' for 1st argument"
}
我的意思是在这个函数里面,r
的类型是什么?不就是int&&
吗(参数是int&& r
所以r
怎么不是int&&
类型的?)如果是这样为什么我不能传这个r
到此函数本身,它采用 int&&
类型作为参数?
r
的类型到底是什么? int&&
还是 int
?如果 int
,为什么?
非常好的读物是Value categories。
是的,变量r
的类型确实是int&&
。然而这里重要的是表达式和:
Each C++ expression (an operator with its operands, a literal, a
variable name, etc.) is characterized by two independent properties: a
type and a value category. Each expression has some non-reference
type, and each expression belongs to exactly one of the three
primary value categories: prvalue, xvalue, and lvalue.
表达式r
是一个左值:
lvalue
The following expressions are lvalue expressions:
- the name of a variable [...], regardless of type. Even if the variable's type is rvalue reference, the expression consisting of its
name is an lvalue expression;
Rvalue 引用可以绑定到纯右值或 xvalue,但不能绑定到 lvalues,所以如果你想将右值引用绑定到 r
,你需要将 r
转换为 xvalue。这是通过 std::move
完成的,尽管它的名字只是一个演员表。
你可以很容易地这样推理:如果它有一个名字那么它就是一个左值(即使那个 id 的类型是右值引用)。您不能将右值引用(原则上应该绑定到临时对象)绑定到具有名称的对象。有名字的东西可以重复使用。您需要 std::move
才能 启用从该左值移动。
关于消息“'int' 没有已知的转换”。如上所示,表达式 r
的类型是 int
,但是更合适的诊断消息应该是这样的:“rvalue reference cannot bind to lvalue”。
确实更新的 clang 和 gcc 提供了更好的消息:
gcc
error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
铿锵
candidate function not viable: expects an rvalue for 1st argument
我这里有一个非常简单的函数定义:
void testRvalue(int&& r)
{
printf("rvalue ref is called\n");
testRvalue(r); // this line gives "no known conversion from 'int' to 'int &&' for 1st argument"
}
我的意思是在这个函数里面,r
的类型是什么?不就是int&&
吗(参数是int&& r
所以r
怎么不是int&&
类型的?)如果是这样为什么我不能传这个r
到此函数本身,它采用 int&&
类型作为参数?
r
的类型到底是什么? int&&
还是 int
?如果 int
,为什么?
非常好的读物是Value categories。
是的,变量r
的类型确实是int&&
。然而这里重要的是表达式和:
Each C++ expression (an operator with its operands, a literal, a variable name, etc.) is characterized by two independent properties: a type and a value category. Each expression has some non-reference type, and each expression belongs to exactly one of the three primary value categories: prvalue, xvalue, and lvalue.
表达式r
是一个左值:
lvalue
The following expressions are lvalue expressions:
- the name of a variable [...], regardless of type. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;
Rvalue 引用可以绑定到纯右值或 xvalue,但不能绑定到 lvalues,所以如果你想将右值引用绑定到 r
,你需要将 r
转换为 xvalue。这是通过 std::move
完成的,尽管它的名字只是一个演员表。
你可以很容易地这样推理:如果它有一个名字那么它就是一个左值(即使那个 id 的类型是右值引用)。您不能将右值引用(原则上应该绑定到临时对象)绑定到具有名称的对象。有名字的东西可以重复使用。您需要 std::move
才能 启用从该左值移动。
关于消息“'int' 没有已知的转换”。如上所示,表达式 r
的类型是 int
,但是更合适的诊断消息应该是这样的:“rvalue reference cannot bind to lvalue”。
确实更新的 clang 和 gcc 提供了更好的消息:
gcc
error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
铿锵
candidate function not viable: expects an rvalue for 1st argument