使用 new 和 值进行数组初始化,但没有显式数量的元素

Array initiliazation using new and values but no explicit number of elements

本文关键字:元素 new 初始化 数组 使用      更新时间:2023-10-16

在许多C系列语言中,可以使用初始元素列表中隐含的元素数量初始化数组。 例如在Java中:

int[] ints = new int[] {0, 1, 2, ...}

在"编程:使用C++的原则和实践"的第597页,Stroustrup写道,可以在C++中使用类似的语法:

double* p5 = new double[] {0, 1, 2, 3, 4};

但是,当尝试使用 GCC 或 Clang 编译它时,我收到错误,因为括号中需要一个表达式:

$ g++ main.cpp
main.cpp: In function 'int main()':
main.cpp:17:26: error: expected primary-expression before ']' token
double* p5 = new double[]{0, 1, 2, 3, 4};
^
main.cpp:17:41: error: too many initializers for 'double [1]'
double* p5 = new double[]{0, 1, 2, 3, 4};
^

与叮当声:

$ clang++ main.cpp
main.cpp:17:26: error: expected expression
double* p5 = new double[]{0, 1, 2, 3, 4};
^
main.cpp:17:19: error: excess elements in scalar initializer
double* p5 = new double[]{0, 1, 2, 3, 4};
^         ~~~~~~~~~~~~~
2 errors generated.

这本书在这一点上有错吗?我看到至少有一个 SO 用户向有不相关问题的人推荐这个(该代码也没有为我编译(。

这似乎是书中的一个错误。 C++中的数组不是像 Java 这样的对象,它是内存中的一个块,它有一个指向第一个元素的指针,因此语法new double[] {}不合理。

用:

double * d = {1,2,3,4};

C++允许在数组声明中省略数组的大小,大小可以从初始值设定项中推断出来,例如:

double d[] = { 0, 1, 2, 3, 4 };   // ok 5 elements
char std[] = "foo";               // ok 4 elements with the terminating null

double* p5 = new double[5];不是数组声明。它声明一个原始指针,该指针被初始化为指向动态分配的数组。

这两个声明都有非常接近的语义,因为例如都允许部分初始化(double* p5 = new double[5]{0, 1, 2};(。但是您提出的语法未在标准中定义,并且不被当前版本的 Clang 或 gcc 接受。

扩展语言以接受它很容易,但恕我直言,这不太可能发生:

  • 数组不是语言的第一类元素,建议程序员使用容器代替
  • 原始指针不再是第一类元素,建议程序员改用引用或智能指针