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功能,在所有情况下,这些功能似乎都不符合我的期望。
答案 0 :(得分:2)
或标准的C ++ 11功能,在所有情况下似乎都不符合我的期望。
然后你有错误的期望 - 至少在decltype
的情况下。我不知道gcc的typeof
是如何工作的,所以我无法回答为什么B)有效,但C)没有,但D)和E)的行为符合标准。
D)此示例中decltype
的表达式为a
。 a
是变量的名称。换句话说,它是一个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]
- 表达方式 Ë ,表示的类型 decltype(e)中 定义如下:
醇>- 如果 Ë 是一个没有特征的 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];