Почему указатели на символы не могут быть определены как массивы? - PullRequest
0 голосов
/ 02 сентября 2018

Простой вопрос. Я знаю, что должен просто использовать std::string, но мне любопытно, почему это работает:

const char* example = "test";

в то время как это приводит к "слишком большому количеству значений инициализатора" для второго символа?

const char* example = {0x74, 0x65, 0x73, 0x74, 0x00};

Разве эти две вещи не должны быть в точности эквивалентны?

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Разве эти две вещи не должны быть в точности эквивалентны?

Во втором примере вы пытаетесь инициализировать указатель, используя инициализация списка копирования , что довольно далеко с точки зрения эквивалентности по сравнению с вашим первым примером.

В противном случае (, если T не является типом класса ), , если в фигурном списке инициализации есть только один элемент и либо T не является ссылочным типом или является ссылочным типом совместимый с типом элемента , T равен с прямой инициализацией (в прямой инициализации списка) или с инициализацией копирования (в copy-list-initialization), за исключением того, что сужающие преобразования не допускается.

Даже если вы поставляете только один элемент :

const char* example = {0x74};

чтобы компилятор не жаловался на количество аргументов, это все равно ошибка, потому что для действительного copy-initialization вам нужно указать указатель , а не int.

char a = 'c';
const char* example = {&a};
0 голосов
/ 02 сентября 2018

Разница в том, что строковые литералы являются собственными массивами. "test" используется здесь не как инициализатор массива (особый случай, когда он будет эквивалентен { 't', 'e', 's', 't', '\0' }), но так же, как любое другое значение.

Другими словами, когда вы используете строковый литерал "test" в своем коде, компилятор автоматически создает что-то вроде

static const char __str_literal0[] = {'t', 'e', 's', 't', '\0'};

, а затем

const char *example = "test";

компилируется, как если бы это было

const char *example = __str_literal0;

т.е. он просто указывает на (уже существующий, статический) массив символов.

С другой стороны, если вы попытаетесь использовать список инициализаторов, компилятор установит первое поле вашей переменной (это просто example) на первое значение в списке инициализаторов (example = 0x74), и затем пожаловайтесь, что в вашем списке слишком много инициализаторов.

...