C++11:"decltype(1+2)" 声明了一个 xvalue 还是一个 prvalue?

C++11: does "decltype(1+2)" declare an xvalue or a prvalue?

decltype(1+2) 是否声明了一个 xvalue 或 prvalue?

cppreference 说,decltype(expression) 将声明: 1. T&& if expression 是一个xvalue 2. T 如果表达式是纯右值 3. T& 如果表达式是左值

但我的问题是:如何生成作为 xvalue 的表达式?我想 return value 和 temp 对象应该是 xvalue,但实际上它们似乎是 xvalue,在我的实验中:

struct S{};
S f();
int main()
{
    int i=2;
    decltype(i+1) j=i;
    ++j;
    printf("i=%d\n",i);
    S obj;
    decltype(f()) k=obj;

    return 0;
}

这个程序编译:我可以判断

decltype(i+1) declares (i+1) as a prvalue

因为如果它是一个 xvalue,则 decltype 得到 T&&,它不能绑定到 "i" 的左值变量。 decltype(f()) 也给我 f() 作为纯右值也很奇怪?

所以我的问题是:如何编写表达式以便 decltype(expression) 给我一个 xvalue? 谢谢。

Decltype 解析为类型,而不是表达式 - 你不能说它 "declares a prvalue" 或类似的东西。

i+1 是纯右值,而不是 id 表达式。所以 decltype 产生一个非引用类型:decltype(i+1) j = i; 表示 int j = i;.

第二种情况类似; f() 是纯右值,所以 decltype(f())S.

要让 decltype(expression) 解析为右值引用类型,表达式必须是一个 xvalue。例如 decltype( std::move(f()) )S&&.

假设T不是引用类型。那么:

  • 对于T f();,类型decltype(f())T
  • 对于T& f();,类型decltype(f())T&
  • 对于T&& f();,类型decltype(f())T&&

所以让decltype产生一个右值引用的方法是将它应用到一个xvalue表达式,例如,std::move(1 + 2).