Инициализация массива с использованием новых и значений, но без явного числа элементов - PullRequest
0 голосов
/ 03 октября 2018

Во многих языках семейства C можно инициализировать массив с количеством элементов, неявных в списке исходных элементов.Например, в Java:

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

На странице 597 «Программирование: принципы и практика с использованием C ++» Страуструп пишет, что в 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:

 $ 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-пользователя, который рекомендовал это кому-то, у кого не было проблем (этот код для меня тоже не компилировался).

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

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.

Было бы легко расширить язык, чтобы принять его, но ИМХО это вряд ли произойдет:

  • массивы не являются элементами первого класса языка, и программистам рекомендуется использовать вместо них
  • необработанные указатели больше не являются элементами первого класса, а программистам рекомендуется использовать ссылки или умные указателивместо
0 голосов
/ 03 октября 2018

Кажется, ошибка в книге.Массивы в C ++ не являются объектами, подобными Java, это блок памяти, в котором указатель указывает на первый элемент, поэтому синтаксис new double[] {} не является разумным.

use:

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