int * в константный массив

Я задал этот вопрос: Эквивалент массива Bare-String

На что ответ был C ++ не предоставляет эту функциональность для const int*s. Что разочаровывает. Поэтому мой вопрос: На практике, как мне обойти это ограничение?

Я хочу написать такую ​​структуру:

struct foo{
const char* letters = "abc";
const int* numbers = ???
};

Я не могу:

  1. &{1, 2, 3} потому что я не могу взять адрес r-значения
  2. array<int, 3>{{1, 2, 3}}.data() потому что память очищается сразу после инициализации
  3. const int* bar(){ return new int[3]{1, 2, 3}; } ничто не удалит этот указатель

Я знаю, что могу использовать автоматический указатель, чтобы обойти это. Я не предполагаю, что struct foo хороший код, я пытаюсь проиллюстрировать, что компилятор обеспечивает хранение константного массива "abc" в памяти и очистить его при выходе из программы, я хочу, чтобы был способ сделать это для intтакже.

Есть ли способ сделать это?

2

Решение

Как насчет статики, на которую вы указываете — я думаю, что именно это компилятор делает для себя "strings literals" тем не мение?

static const int Numbers[] = {1, 2, 3};

struct foo{
const char* letters = "abc";
const int* numbers = Numbers;
};
6

Другие решения

Строковые литералы — это все, что вы получаете. Однако их также достаточно, чтобы охватить большинство интегральных данных. В вашем случае вы можете использовать

L"\1\2\3"

получить управляемый компилятором массив широких символов. C ++ 11 и более поздние версии также поддерживают u8, u16, а также u32 строки.

2

Мы можем сделать это, используя Бен Фойгтответ:

const int* numbers = sizeof(int) == sizeof(char32_t) ? reinterpret_cast<const int*>(U"\1\2\3") : reinterpret_cast<const int*>(u"\1\2\3");

Троица составлена, о чем свидетельствует тот факт, что вы можете объявить numbers как constexpr,

У этой реализации есть пара недостатков:

  1. Это на самом деле wchar_t строковый литерал вы получите завершающий 0 элемент в дополнение к любым символам, которые вы укажете
  2. Это предполагает, что int будет либо 32-битным, либо 16-битным, если это не так, он попытается привести из char16_t к любому размеру int и у вас будут большие проблемы

В любом случае мы можем упростить это до макроса:

#define QUOTATION(x) sizeof(int) == sizeof(char32_t) ? reinterpret_cast<const int*>(U ## x) : reinterpret_cast<const int*>(u ## x)

Который может быть использован как:

const int* numbers = QUOTATION("\1\2\3");
1
По вопросам рекламы [email protected]