使用typeof和decltype

时间:2015-11-13 11:11:29

标签: c++ typeof decltype

A)这有效:

int main() {
    int * a = new int[5];
    delete[] a;
    return 0;
}

B)出错:

int main() {
    int * a = new typeof(*a)[5];
    delete[] a;
    return 0;
}

有错误:无效类型' int [int]'对于数组下标

C)这有效:

int main() {
    int * a = new typeof(a)[5];
    delete[] a;
    return 0;
}

我无法理解为什么B会失败,因为在扩展后声明应如下所示:

int *a = new int[5];

因为typeof(*a)是int。

这是使用decltype的实验:

D)这不起作用:

int main() {
    int * a = new decltype(a)[5];
    delete[] a;
    return 0;
}

有错误:无法转换' int **'到' int *'在初始化。这是预期的,因为decltype(a)是int *所以它转换为int *a = new int*[5];这是不正确的。

E)但这不起作用:

int main() {
    int * a = new decltype(*a)[5];
    delete[] a;
    return 0;
}

有错误:new无法应用于引用类型

无论是GCC扩展还是标准的C ++ 11功能,在所有情况下,这些功能似乎都不符合我的期望。

2 个答案:

答案 0 :(得分:2)

  

或标准的C ++ 11功能,在所有情况下似乎都不符合我的期望。

然后你有错误的期望 - 至少在decltype的情况下。我不知道gcc的typeof是如何工作的,所以我无法回答为什么B)有效,但C)没有,但D)和E)的行为符合标准。

D)此示例中decltype的表达式为aa是变量的名称。换句话说,它是一个id表达式。在id-expression的情况下,decltype解析为实体的类型。 a的类型为int*。因此new decltype(a)[5];构造了一个int*数组。由于a的类型不是int**,因此无法指向int*的数组。

E)此示例中decltype的表达式为*a。表达式的类型(T)为int。但*a不是变量的名称。它不是a之类的id表达式。 *a的值类别是左值。如果是左值表达式,decltype将解析为T&,其中T是表达式的类型。因此,decltype(*a)int&。不允许使用引用数组,因此不允许使用new decltype(*a)[5]

以下是标准(草案)的引用:

§7.1.6.2[dcl.type.simple]

  
      
  1. 表达方式   Ë   ,表示的类型   decltype(e)中   定义如下:
  2.         

    -    如果   Ë   是一个没有特征的   ID-表达   或不受干扰的班级成员访问(   5.2.5   )   decltype(e)中   是由...命名的实体的类型   Ë   。如果没有这样的实体,或者如果   Ë   命名一组重载函数   这个计划是不正确的;

         

    -    否则,如果   Ë   是一个x值,   decltype(e)中   是   T&安培;&安培;   ,哪里   Ť   是的类型   Ë   ;

         

    -    否则,如果   Ë   是一个左值,   decltype(e)中   是   T&安培;   ,哪里   Ť   是的类型   Ë   ;

         

    -    除此以外,   decltype(e)中   是的类型   ë

这是正确的:

int * a = new std::remove_pointer<decltype(a)>::type[5];

还有这个:

int * a = new std::remove_reference<decltype(*a)>::type[5];

当然,这两者都是毫无意义的复杂。如果您的目标是避免重复该类型,那么decltype不是您应该寻找的工具。适合您需求的工具是auto

auto a = new int[5];

答案 1 :(得分:1)

* a是指向int的指针,因此无法通过这种方式调用typeof

int *a = new int[5];

有效,因为您显示整数并在显示

的位置声明大小为5的新数组

也许你想要:

typeof(new typeof(int *)[5])a;

代替

 int * a = new typeof(*a)[5];