Search code examples
c++arraysinitialization

How to initialize an array of struct in C++ while specifying array index explicitly


I am a little new to C++ and learning the language. Right now I'm using C++17 and GCC. I have the following struct named Spec in my C++ code.

struct Spec
{
    int val;
    double otherVal;
};

And I have an array named specData of these structs. I know in advance (at compile time) the values of the structs in my array. Thus, I can initialize my array as follows:

Spec specData[] = { 
        { .val = 1, .otherVal = 3.56 }, 
        { .val = 3, .otherVal = 9.88 },
    } ;

However, the index of each entry is important. I want to explicitly map each element in the array with some index which I will be giving an int-alias so it is clear to which subject each Spec belongs. In my code, I can then easily access the specData using the int-alias also. (My intent is that this helps to ease maintenance and to make it less error prone).

Suppose I have an Spec for each of these entries (this could be my int-alias for example):

enum class Items
{
    ITEM_NAME1   = 0,
    ANOTHER_ITEM = 1,
};

Then, I want to initialize my array something like this:

Spec specData[] = { 
        [Items::ITEM_NAME1]   = { .val = 1, .otherVal = 3.56 }, 
        [Items::ANOTHER_ITEM] = { .val = 3, .otherVal = 9.88 },
    } ;

This obviously does not compile.

I know it seems like I might better use: std::map<Items, Spec>. Altough that would probably work, however, map has an O(log N) complexity, while an array look-up is O(1) complexity. I will be looking up lots of values, so I would like to have the extra speed.

Is it possible to initialize my array like the way I want? If not, what is the second best alternative?


Solution

  • I would use a constexpr method and manually assign the entries one-by-one. Its all evaluated at compile time, so it's not any slower.

    constexpr std::array<Spec, 2> make_spec_data() {
        std::array<Spec, 2> array{};
        array[(int)Items::ITEM_NAME1] = { 1, 3.56 };
        array[(int)Items::ANOTHER_ITEM] = { 3, 9.88};
        return array;
    }
    constexpr std::array<Spec, 2> specificationData = make_spec_data();