`decltype`会给我一个对象的静态类型,还是它的运行时类型?

时间:2013-04-09 10:21:13

标签: c++ c++11 language-lawyer decltype

  

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

     
      
  • 如果e是未加密码的 id-expression 或未加密码的类成员访问(5.2.5),decltype(e)是由{{1}命名的实体的类型}}。如果没有这样的实体,或者e命名了一组重载函数,那么该程序就是格式错误;
  •   
  • 否则,如果e是xvalue,则edecltype(e)T&&的类型为T;
  •   
  • 否则,如果e是左值,则edecltype(e)T&的类型为T;
  •   
  • 否则,edecltype(e)
  • 的类型   
     

e说明符的操作数是未评估的操作数(第5条)。

第二,第三和第四个案例清楚地引用了表达式的类型,它不包括任何多态性因素。

但是,我并不完全确定“ entity ”在这里意味着什么,第一个案例似乎是在命名 object 引用通过表达式decltype。对于我来说,“实体的类型”是指其运行时类型还是静态类型是不明确的。

3 个答案:

答案 0 :(得分: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是类型为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’
}

这就是为什么,根据these answers,它始终是使用的对象的静态类型

答案 1 :(得分:6)

您无需查看各个点:结果 decltype是编译器已知的类型,非常漂亮 很多动态打字都不包括在内。你最后一行 引用不能更明确:不评估说明符, 这也排除了任何动态类型。

答案 2 :(得分: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的类型为const int还是int?如果您将 entity 表示为“member”,则为int,因为成员A::a的类型为int。如果您使用实体类型“对象”,则类型为const intint,具体取决于rand()的结果。对象,它们的存在和属性(包括它们的类型)是一个运行时问题。

我说这不是一个真正含糊不清的问题。因为每个人都知道这是什么意思,因为标准使用短语“由e命名”而不是“由e引用”或“由e表示”,表示只是查询它的名称查找结果。

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