Return decltype() 的类型

Return type of decltype()

在下面的代码中,为什么 decltype(++c) returns int& 而不是 intdecltype(a++) return int .

#include <iostream>
#include <typeinfo>

int main()
{
    int32_t a {};
    decltype(a++) b; // OK

    int32_t c{};
    decltype(++c) d; // error: 'd' declared as reference but not initialized

    std::cout << "typeid(b) = " << typeid(b).name() << std::endl;
    std::cout << "typeid(d) = " << typeid(d).name() << std::endl;
}

built-in pre-increment 运算符的结果是一个引用操作数的左值(然后在递增后保存值)。这意味着,例如,++a = 1; 是有效的。 ++a的结果引用了变量a,可以赋值1.

built-in post-increment 运算符的结果是操作数前一个值的纯右值(它不能是引用操作数的左值,因为 post-increment 应该是在增量之前给出 previous 值)。这意味着,例如 a++ = 1; 无效,因为 a++ 的结果不是指 a,而只是 a 的原始值,并且值不能没有被赋值。

decltype 应用于纯右值表达式给出 non-reference。应用于左值表达式,它给出了表达式类型的左值引用。这模仿了 return 类型,如果重载增量运算符,您需要使用这些类型来为表达式获取相同的值类别。

这是标准中前缀和后缀运算符描述的结果。

cppreference 有一点 table 显示两个运算符的签名,其中 ut 表示:

Prefix versions of the built-in operators return references and postfix versions return values...

根据定义,pre-increment 运算符 returns 一个 reference,就好像它是这样声明的:

T& T::operator++();
T& operator++(T& a);

post-increment运算符returns一个:

T T::operator++(int);
T operator++(T& a, int);

要避免错误尝试

#include <type_traits>
//   
// ...later...
//
std::remove_reference_t<decltype(++c)> d;