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

Lig*_*ica 10 c++ decltype language-lawyer c++11

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

  • if e是未加密码的id-expression或未加括号的类成员访问(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.对于我来说,"实体的类型"是指其运行时类型还是静态类型是不明确的.

Lig*_*ica 8

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

考虑:

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

int main()
{
   A* x = new B();
   // What is `decltype(*x)`?
}
Run Code Online (Sandbox Code Playgroud)

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

并提供参考?

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

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

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’
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我不认为说对象具有"静态"类型是有意义的.对象只是一个类型.*表达式*可以具有静态和动态类型(并且始终具有类型).静态类型只是它的类型.动态类型(仅用于glvalues)是glvalue引用的派生最多的对象的类型. (4认同)

Jam*_*nze 6

您不必查看各个点:结果decltype是编译器已知的类型,几乎不包括任何动态类型.并且您引用的最后一行不能更明确:不评估说明符,也不包括任何动态类型.

  • @SebastianRedl我很想说标准的大部分都与奥卡姆剃刀相反.但是,在这种情况下,标准明确定义了动态类型作为评估表达式的结果,并且"decltype"中的表达式未被评估. (2认同)