函数中右值引用参数的类型是什么?

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