诠释一= 3;整数 *p=&a; decltype (a) k1; decltype (*p) k2; k1是int类型,k2是int&类型,为什么?

int a=3; int *p=&a; decltype (a) k1; decltype (*p) k2; k1 is int type and k2 is int& type why?

代码

#include <iostream>
int main()
{
    int a=3;
    int *p=&a;

    decltype (a) k1;
    decltype (*p) k2;
    
    return 0;
}

输出

Declaration of reference variable 'k2' requires an initializer

对这种现象的解释是“decltype returns 一种表达式的引用类型,它产生的对象可以站在赋值的左轴上”

看看 *p 产生它指向的对象的值意味着 3 以及什么 a 产生它本身的值 3.

现在我们操纵性地讲,*p指的是对象a那么a也指的是a本身。

所以我没有消化针对此类现象给出的解释。

引用在本质上与指针没有太大区别。它们都指的是内存中的对象。但我相信你已经知道了。 decltype is that it returns reference in this case. As pointed out in another answer here and mentioned here 的事情, *p 是内置的间接表达式,它是一个左值。所以 decltype 这样做:

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

你也可以验证一下:

std::cout << "*p and int are the same type? " << std::boolalpha
          << std::is_same_v<decltype(*p), int> << '\n'
          << "*p and int& are the same type? " 
          << std::is_same_v<decltype(*p), int&> << '\n';

a 是一个未加括号的 id 表达式。

*p 不是 id 表达式。这是一个间接操作。

decltype 当操作数是未加括号的 id 表达式时的行为与当操作数不是未加括号的 id 表达式时的行为不同。

未加括号的 id 表达式的

decltype 不会生成引用类型,而是生成由 id 表达式命名的实体的类型。 a 命名的实体类型为 int.

decltype 的非无括号 ID 表达式可能会产生左值引用或右值引用或非引用,具体取决于表达式的值类别。 *p 是一个左值表达式,所以 decltype (*p) 产生一个左值引用,即 int&.

see what *p yields value of of the object it points means 3 and what a yields value of itself which is 3.

表达式 a*p 就表达式本身产生的结果而言没有区别。它们都是相同类型的左值表达式,并且命名相同的对象。

区别在于,一个是未加括号的 id 表达式,因此适用于 decltype 的例外情况,而另一个则不是。

根据cppreference

decltype ( expression ) 

If the argument is any other expression of type T, and if the value category of expression is lvalue, then decltype yields T&;

那么现在让我们看看你的例子。特别是,我们有:

decltype (*p) k2;

括号()里面的“东西”是一个表达式。也就是说,*p 是一个表达式。现在有两件重要的事情:

  1. 这个表达式的类型是int
  2. 这个表达式的值类别是一个左值

所以根据上面引用的语句,在我们的例子中结果将是 T& 或 int&

并且由于我们必须始终初始化一个引用,所以您会收到上述错误。