dymanoid dymanoid - 3 months ago 19
C++ Question

What is the proper way to initialize const containers with different values?

I have some container

struct
that holds a set of configuration elements.

struct config
{
const std::vector<int> config_items;
const std::vector<double> another_items;
}


Also, I have a "container of containers" that should hold a known and limited number of instances of those configuration containers (e.g. 3). Each
config
instance should then have different
int
s and
double
s in the corresponding
vector
s.

struct setup
{
const std::vector<config> items;
}


All the
vector
s' items should be
const
, because they should be defined once and never change.

Since the
vector
s are
const
, I can only initialize them in the constructor initializer list. But I want to have multiple instances with different values.

I could create some child
struct
s to create each configuration in the child constructors. But this doesn't work, because I cannot initialize a parent member in the child constructor:

struct config_1 : public config
{
config_1() : config_items { 1, 2 }, another_items { 1.0, 2.0 } {} // Doesn't work
}


This seems to be a very poor decision too (remove
const
, make copies...):

struct config
{
std::vector<int> config_items;
std::vector<double> another_items;
}

struct setup
{
std::vector<config> items;
}

void init()
{
config c;
c.config_items = { 1, 2 };
c.another_items = { 1.0, 2.0 };

setup s;
s.items = { c };
}


I cannot make a single initializer-list constructor too, because I have multiple
vector
s:

struct config
{
config(std::initializer_list<int> i, std::initializer_list<double> d); // No go
std::vector<int> config_items;
std::vector<double> another_items;
}


Background: I want to have a hardcoded
const
config structure (probably placed in the DATA section or even in the flash memory) for my embedded application. No need to read things from any config files etc.

So my question is: what would you suggest me how I should create such a
const
configuration container?




EDIT



The
std::vector
s are actually wrong here. I'm using a custom container that holds the data in the instance like
std::array
and not like
std::vector
which allocates the storage on the heap.

So the environment should rather look like this:

struct config
{
const std::array<int, 2> config_items;
const std::array<double, 2> another_items;
}

struct setup
{
const std::array<config, 3> items;
}

Answer

After some research I've decided to answer my own question.

As NathanOliver and nwp mentioned, the std::vectors used in question allocate the memory on the heap. Actually, I'm using a custom container similar to an std::array that holds the data in the instance itself.

So I should have written something like this in the question:

struct config
{
    const std::array<int, 2> config_items;
    const std::array<double, 2> another_items;
}

struct setup
{
    const std::array<config, 3> items;
}

Now, since these structs are PODs, I can use an aggregate initialization of them:

setup instance
{
    // std::array c++11-ish double-braces aggregate initialization
    // this is the items member
    { {
        {
            // this is the config_items member
            { { 1, 2 } },

            // this is the another_items member
            { { 1.0, 2.0 } },
        },

        {
            { { 3, 4 } },
            { { 3.0, 4.0 } },
        },

        {
            { { 5, 6 } },
            { { 5.0, 6.0 } },
        }
    } }
};

Now, I have an initialized instance struct whose members are const, and there is no run-time code to do initialization (no ctors, no method calls) but rather the raw data will be directly stored in the DATA section (by default). This is exactly what I need.

Comments