I have an array of strings that must be allocated once and their underlying c_str must remain valid for entire duration of the program.
There's some API that provides info about some arbitrary data types. Could look like this:
// Defined outside my code #define NUMBER_OF_TYPES 23 const char* getTypeSuffix(int index); The getTypeSuffix is not constexpr, so this must work at least partially in runtime.
The interface that I must provide:
// Returned pointer must statically allocated (not on stack, not malloc) const char* getReadableTypeName(int type); Now my array should have following type:
std::string typeNames[NUMBER_OF_TYPES]; For my purposes, it will be initialized within a wrapper class, right in the constructor:
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]; }; This is then used in an singleton-ish kind of way, for example:
const char* getReadableTypeName(int type) { static MyNames names; return names[type]; } Now what I want to improve is that I can see that the for loop in the constructor could be replaced as such:
MyNames() : _names{std::string("Type ") + getTypeSuffix(0), std::string("Type ") + getTypeSuffix(1), ... , std::string("Type ") + getTypeSuffix(NUMBER_OF_TYPES-1)} {} Obviously a pseudocode, but you get the point - the array can be initialized directly, leaving the constructor without body, which is neat. It also means that the array member _names can be const, further enforcing the correct usage of this helper class.
I'm quite sure there would be many other uses to filling an array by expressions in compile time, instead of having loop. I would even suspect that this is something that happens anyway during 03.
Is there a way to write a C++11 style array initializer list that has flexible length and is defined by an expression? Another simple example would be:
constexpr int numberCount = 10; std::string numbers[] = {std::to_string(1), std::to_string(2), ... , std::to_string(numberCount)}; Again, an expression instead of a loop.
I'm not asking this question because I was trying to drastically improve performance, but because I want to learn about new, neat, features of C++14 and later.
MyNamesclass. The only public accessor is your operator which provides a constant output. (You could still make the method const) What extra advantage do you want?std::arrayrather than a C-style array?