c++c++11braced-init-list

How to properly use brace enclosed initiator?


I have defined 3 nested structs in my project and want to create a default setup that is used by many functions. I have tried using the following code which the IDE says should work.

struct xBitValue {
    size_t depth=0;
    uint64_t key=1;

    //allow comparison
    bool operator==(const xBitValue& b) const {
        return ((depth==b.depth) && (key==b.key));
    }
    bool operator!=(const xBitValue& b) const {
        return ((depth!=b.depth) || (key!=b.key));
    }
};

struct stringHeaderOption {
    xBitValue header;
    size_t encoder=0;
};

struct stringHeaderOptions {
    size_t xBitLength;
    std::vector<stringHeaderOption> options;
};

const stringHeaderOptions defaultHeaderOptions={2,{
    {{0,1},0},
    {{0,2},1},
    {{0,3},2},
    {{1,1},3}
}};

but I get the error could not convert {{{0, 1}, 0}, {{0, 2}, 1}, {{0, 3}, 2}, {{1, 1}, 3}} from <brace-enclosed initializer list> to std::vector<stringHeaderOption> with an error pointing to the last }.

It seems there is something I am missing on how to initialize values in this way.

C++11


Solution

  • You are aiming for an aggregate initialization. However, In C++11 an aggregate cannot have default member initializers - this was changed in C++14 (See: https://en.cppreference.com/w/cpp/language/aggregate_initialization#Definitions)

    Your code compiles in C++14 and later. It will not work in C++11; See it compile in C++14: http://coliru.stacked-crooked.com/a/8484258abc2e02d6

    It will compile in C++11 if you remove the default values you are giving to the data members of xBitValue and stringHeaderOption. See: http://coliru.stacked-crooked.com/a/eb49bcb837a45f89

    Note: In C++14 and later the following compiles (in C++11 it will result in an error):

    stringHeaderOption s1{1,0,1}; 
    stringHeaderOption s2{1,0};
    stringHeaderOption s3{1};
    

    Therefore, perhaps you would like to only allow constructors that create structs you find legal.