У меня есть массив строк, которые должны быть выделены один раз, и их базовые значения c_str
должны оставаться действительными в течение всей продолжительности программы.
Есть некоторый API, который предоставляет информацию о некоторых произвольных типах данных.Может выглядеть так:
// Defined outside my code
#define NUMBER_OF_TYPES 23
const char* getTypeSuffix(int index);
getTypeSuffix
не constexpr
, поэтому это должно работать хотя бы частично во время выполнения.
Интерфейс, который я должен Обеспечить:
// Returned pointer must statically allocated (not on stack, not malloc)
const char* getReadableTypeName(int type);
Теперь мой массив должен иметь следующий тип:
std::string typeNames[NUMBER_OF_TYPES];
Для моих целей он будет инициализирован внутри класса-оболочки прямо в конструкторе:
class MyNames
{
MyNames()
{
for (int i = 0; i < NUMBER_OF_TYPES; ++i)
{
names[i] = std::string("Type ") + getTypeSuffix(i);
}
}
const char* operator[](int type) { return _names[(int)type].c_str(); }
private:
std::string _names[NUMBER_OF_TYPES];
};
Это затем используется в виде синглтона, например:
const char* getReadableTypeName(int type)
{
static MyNames names;
return names[type];
}
Теперь я хочу улучшить то, что я вижу, что цикл for в конструкторе могможно заменить следующим образом:
MyNames() : _names{std::string("Type ") + getTypeSuffix(0), std::string("Type ") + getTypeSuffix(1), ... , std::string("Type ") + getTypeSuffix(NUMBER_OF_TYPES-1)}
{}
Очевидно, псевдокод, но вы поймете, что массив можно инициализировать напрямую, оставив конструктор без тела, что очень удобно.Это также означает, что член массива _names
может иметь значение const
, что дополнительно способствует правильному использованию этого вспомогательного класса.
Я вполне уверен, что было бы много других применений для заполнения массива выражениями ввремя компиляции вместо циклаЯ даже подозреваю, что это происходит в любом случае во время 03
.
Есть ли способ написать список инициализатора массива в стиле C ++ 11, который имеет гибкую длину и определяется выражением?Другой простой пример:
constexpr int numberCount = 10;
std::string numbers[] = {std::to_string(1), std::to_string(2), ... , std::to_string(numberCount)};
Опять выражение вместо цикла.
Я задаю этот вопрос не потому, что пытался радикально улучшить производительность, а потому, что хочучтобы узнать о новых, изящных, особенностях C ++ 14 и более поздних версий.