"decltype"是否为我提供了对象的静态类型或其运行时类型?

Does `decltype` give me an object's static type, or its runtime type?

本文关键字:类型 静态类 静态 运行时 对象 是否 decltype      更新时间:2023-10-16

[C++11: 7.1.6.2/4]:decltype(e)表示的类型定义如下:

  • 如果e是未加括号的id表达式或未加括号类成员访问(5.2.5(,则decltype(e)是由e命名的实体的类型。如果没有这样的实体,或者如果e命名了一组重载函数,则程序是格式错误的
  • 否则,如果e是x值,则decltype(e)T&&,其中Te的类型
  • 否则,如果e是左值,则decltype(e)T&,其中Te的类型
  • 否则,decltype(e)e的类型

decltype说明符的操作数是未赋值的操作数(第5条(。

第二种、第三种和第四种情况清楚地提到了表达的类型,其中不包括任何多态性因素。

然而,我不完全确定">实体"在这里是什么意思,第一个情况似乎是命名表达式e引用的对象。"实体的类型"是指它的运行时类型,还是静态类型,我对此并不清楚。

由于第一种情况的限制,实际上不可能遇到这个问题。

考虑:

struct A     {};
struct B : A {};
int main()
{
   A* x = new B();
   // What is `decltype(*x)`?
}

CCD_ 21的使用使我们陷入了第三种情况。

作为参考?

struct A     {};
struct B : A {};
int main()
{
   A& x = *(new B());
   // What is `decltype(x)`?
}

x是一个类型为A&的引用,它是"实体"的类型结果。

使用第一种情况的唯一方法是直接命名对象,而我们不能以隐藏运行时类型的方式这样做:

struct A     {};
struct B : A { void foo() {} };
int main()
{
   A x = B();     // well, you've sliced it now, innit?
   decltype(x) y;
   y.foo();       // error: ‘struct A’ has no member named ‘foo’
}

这就是为什么根据这些答案,总是使用对象的静态类型

您不必查看各个点:结果decltype是编译器已知的类型很大程度上排除了任何动态类型。还有你说的最后一句话引号再明确不过了:没有对说明符求值,这也排除了任何动态打字。

这基本上是一个"实体"在这里意味着什么的问题(可能的含义在第3条中定义(。考虑

struct A {
  int a;
};
int main() {
  A a = {};
  const A b = {};
  const A *aptr = (rand() % 42) ? &a : &b;
  decltype(aptr->a) x = 0;
  decltype((aptr->a)) y = 0;
}

x的类型是const int还是int?如果将实体表示为"成员",则它是int,因为成员A::a的类型为int。如果采用实体类型"object",则类型为const intint,具体取决于rand()的结果。对象、它们的存在和属性(通常包括它们的类型(是一个运行时问题。

我要说的是,这并不是真正的模棱两可。因为每个人都知道这是什么意思,因为标准使用了短语"由e命名",而不是"由e引用"或"由e表示",这表明它只是名称查找结果。

注意,y的类型是始终const int&,因为表达式aptr->a的类型是const int,并且它是左值。