decltype(rvalue expr) 的类型推导规则是什么?

What are the type deduction rules of decltype(rvalue expr) ?

我看过 Scott Meyers 解释的关于 auto 和 decltype 的类型推导规则的视频......他解释了以下内容

// decltype(lvalue expr) => reference to the type of the expression
// decltype(lvalue name) => type of the name

我明白这些规则...但他没有解释以下内容

// decltype(rvlaue expr) => ???

所以我试图通过练习来理解它,所以我做了以下事情

int x = 8;
int func();  // calling this function is rvlaue expr ...

decltype(32) t1 = 128;    // Ok   t1 is int
decltype(64) t2 = x;      // Ok   t2 is int 
decltype(func()) t3 = x;  // Ok   t3 is int ... obviously

现在魔法

decltype(std::move(x)) t4 = x;  // Error t4 is int&& ... compiler says

std::move(x) 不是右值表达式吗?为什么 decltype 将 t4 推导为 int&& 而不是像上面的例子那样只是 int? 右值表达式的decltype类型推导规则是什么?

decltype 根据其使用的类型不同表现不同

if the value category of expression is xvalue, then decltype yields T&&;

if the value category of expression is lvalue, then decltype yields T&;

if the value category of expression is prvalue, then decltype yields T.

如您所见,它对右值有两种不同的行为。如果右值是一个 xvalue,那么我们得到 T&& 否则它是一个 prvalue,我们得到 T.

现在,如果我们查看 std::move,我们会发现它 return 是一个 xvalue,因为 return 是 T&& 而不是 T.所以 std::move(x) 是一个 xvalue 并且被正确推导为 int&&