Я задал этот вопрос: Эквивалент массива Bare-String
На что ответ был C ++ не предоставляет эту функциональность для const int*
s. Что разочаровывает. Поэтому мой вопрос: На практике, как мне обойти это ограничение?
Я хочу написать такую структуру:
struct foo{
const char* letters = "abc";
const int* numbers = ???
};
Я не могу:
&{1, 2, 3}
потому что я не могу взять адрес r-значенияarray<int, 3>{{1, 2, 3}}.data()
потому что память очищается сразу после инициализацииconst int* bar(){ return new int[3]{1, 2, 3}; }
ничто не удалит этот указательЯ знаю, что могу использовать автоматический указатель, чтобы обойти это. Я не предполагаю, что struct foo
хороший код, я пытаюсь проиллюстрировать, что компилятор обеспечивает хранение константного массива "abc"
в памяти и очистить его при выходе из программы, я хочу, чтобы был способ сделать это для int
также.
Есть ли способ сделать это?
Как насчет статики, на которую вы указываете — я думаю, что именно это компилятор делает для себя "strings literals"
тем не мение?
static const int Numbers[] = {1, 2, 3};
struct foo{
const char* letters = "abc";
const int* numbers = Numbers;
};
Строковые литералы — это все, что вы получаете. Однако их также достаточно, чтобы охватить большинство интегральных данных. В вашем случае вы можете использовать
L"\1\2\3"
получить управляемый компилятором массив широких символов. C ++ 11 и более поздние версии также поддерживают u8
, u16
, а также u32
строки.
Мы можем сделать это, используя Бен Фойгтответ:
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
,
У этой реализации есть пара недостатков:
wchar_t
строковый литерал вы получите завершающий 0 элемент в дополнение к любым символам, которые вы укажете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");