10

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

  • ife是不带括号的id 表达式或不带括号的类成员访问 (5.2.5),decltype(e)是由 命名的实体的类型e。如果没有这样的实体,或者如果e命名了一组重载函数,则程序是非良构的;
  • 否则,如果e是一个 xvalue,decltype(e)T&&,其中T的类型是e;
  • 否则,如果e是左值,decltype(e)T&,其中T的类型是e
  • 否则,decltype(e)是 的类型e

说明符的操作数decltype是未计算的操作数(第 5 条)。

第二种、第三种和第四种情况清楚地涉及表达式的类型,其中不包括任何多态性考虑。

但是,我不完全确定这里的“实体”是什么意思,第一种情况似乎是命名表达式引用的对象e。对于“实体的类型”是指它的运行时类型还是它的静态类型对我来说是模棱两可的。

4

3 回答 3

8

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

考虑:

struct A     {};
struct B : A {};

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

的使用*使我们陷入第三种情况。

并作为参考?

struct A     {};
struct B : A {};

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

x是一个 type 的引用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’
}

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

于 2013-04-09T10:21:13.043 回答
6

您不必查看各个点: 的结果decltype是编译器已知的类型,几乎不包括任何动态类型。你引用的最后一行再明确不过了:说明符没有被评估,这也排除了任何动态类型。

于 2013-04-09T11:26:13.943 回答
0

这基本上是“实体”在这里意味着什么的问题(可能的含义在第 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's 类型const int还是int? 如果您将entity表示“成员”,那是int因为该成员A::a具有 type int。如果您采用实体类型“对象”,则类型为const intint,具体取决于 的结果rand()。对象、它们的存在和属性(包括它们的一般类型)是一个运行时问题。

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

请注意, 的类型y总是,因为表达式的类型是并且 它是一个左值。const int&aptr->aconst int

于 2013-04-09T17:00:43.510 回答