【问题标题】:int a=3; int *p=&a; decltype (a) k1; decltype (*p) k2; k1 is int type and k2 is int& type why?诠释一个= 3; int *p=&a; decltype (a) k1; decltype (*p) k2; k1 是 int 类型而 k2 是 int& 类型为什么?
【发布时间】:2021-12-21 07:00:49
【问题描述】:

代码

#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 为表达式返回一个引用类型,该表达式产生的对象可以位于赋值的 LHS 上”

看看*p 产生的对象的值意味着3,以及a 产生的自身值是3

现在我们操纵性地讨论*p 指的是对象a 然后a 也指的是a 本身。

所以我没有消化对这种现象的解释。

【问题讨论】:

标签: c++ reference decltype rvalue lvalue


【解决方案1】:

a 是一个不带括号的 id 表达式。

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

decltype 在操作数是无括号的 id 表达式时与操作数不是无括号的 id 表达式时的行为不同。

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

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

看看 *p 它所指向的对象产生的值是什么意思是 3,以及 a 产生的值是什么,它本身是 3。

表达式 a*p 在表达式本身产生的内容方面没有区别。它们都是相同类型的左值表达式并且命名相同的对象。

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

【讨论】:

  • 等等decltype ((a)) k3; /*int&amp; k3;*/
  • @eerorika 1. 那么如何将一个表达式归类为不带括号的 id 表达式呢? 2. 以及不带括号的 id 表达式究竟是什么意思? 3. 关于yield either an lvalue reference or an rvalue reference or a non-reference,这里的非参考意味着您在谈论rvalue,对吗?
  • @Tylerdurden what is unqualified-id unqualified-id 是标识符、操作符函数 ID、转换函数 ID、文字操作符 ID、~type-name、~decltype-specifier 或模板- ID。 or a qualified-idqualified-id 是嵌套名称说明符,可选地后跟模板,后跟 unqualified-id。 is id representing identifier here ? 我相信 id 与标识符有关,是的。 int, float , char are identifiers right ? 不对。这些不是标识符,而是 type-ids。此外,它们不是 id 表达式。 a 是一个标识符,因此是一个 id 表达式。
  • @Tylerdurden Literals、this、运算符表达式、lambda、折叠、强制转换、收益、抛出例如。
  • @Tylerdurden 1. 因为 3 是纯右值,因此 decltype 产生非引用。 2. 应该是int*&amp;,但是你不能默认初始化引用,所以它的格式不正确。指针类型不是引用。引用类型不是指针。是的,这些是算术类型的示例。 3. 是的,A 将是一个类类型。 4.void(int,int)
【解决方案2】:

根据cppreference

decltype ( expression ) 

如果参数是任何其他类型为 T 的表达式,并且如果表达式的值类别是左值,则 decltype 产生 T&;

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

decltype (*p) k2;

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

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

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

而且由于我们必须始终初始化一个引用,所以你会得到所说的错误。

【讨论】:

    【解决方案3】:

    从本质上讲,引用与指针没有太大区别。它们都指的是内存中的对象。但我相信你已经知道了。 decltype 的问题是它在这种情况下返回引用。正如此处另一个答案中所指出的并提到here*p 是内置的间接表达式,它是一个左值。所以 decltype 这样做:

    b) 如果表达式的值类别是左值,则 decltype 产生 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';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 2017-05-29
      • 1970-01-01
      • 2012-02-03
      • 2010-11-02
      • 2013-08-14
      相关资源
      最近更新 更多