Инициализация массива сhar'ов

const char k[3]={1,2,3};
char v[3] = k;
char d[] = "kk";  // const char[3]kk но еще это и константный литерал

Не очень понимаю, почему возможно инициализировать массив константным литералом, который также является массивом, а обычный массив нет. Понимаю, что должно быть посимвольное копирование в случае обычного массива,но почему работает во втором случае?


Ответы (1 шт):

Автор решения: Swift - Friday Pie

Можно еще и так

const char d[3] = "kk";       // низя без const
char d2[3] = {'k','k','\0'};  // а этот массив можно менять

Это отдельные случаи. Литерал и список инициализации не являются массивами, это результаты этих выражений могут являться массивами. Проблема с

const char k[3]={1,2,3};
char v[3] = k;

в том, что с легкой руки г-на Кёнига и ради совместимости с Си, результат выражения k - это prvalue с типом const char*. Оно должно являться таковым, иначе стандартное определение оператора [] в выражении k[2] не будет работать - он требует того, чтобы один аргумент был prvalue, а другой - приводимым к значению, которое можно сложить с ним, т.е. это *(k + 2)[1]. const char* не совместим с char[3] и размер массива уже не известен.

Выходом из ситуации является использование агрегатной инициализации:

   struct Ar {
      char data[3];
   };
   Ar v1 = {"kk"};
   Ar v2 = v1;

Если сделать класс Ar шаблоном, мы получим прототип стандартного класса std::array:

   std::array<char, 10> v1 = {"kk"};
   auto v2 = v1;

[1] А в результате `2[k]` - тоже легальное выражение.
→ Ссылка