Search code examples
c++constructorinitializationinitializer-list

C++: Curly Braces Initialization Despite Explicit Constructor


I've had a data class (so like a struct in the C sense: a class with only a bunch of properties) that I used to initialize (through an implicit copy constructor, I think) with curly braces initializer lists, like so:

ClassName inst = {1, 2, 3, 4};

I then decided I want to enable initialization from vectors, so I defined a ctor looking something like this:

ClassName(std::vector<int> vec) : A(vec[0]), B(vec[1]), C(vec[2]), D(vec[3]) {}

Ever since adding this constructor, though, the above-cited method of curly-braces-initialization no longer works due to "cannot conver from 'initializer list' to 'namespace::ClassName'".

I tried Googling for explanations/advice/solutions but couldn't find the right keywords and nothing I found seemed to answer my question exactly.

How would you advise getting around this (whether specifically how to re-enable such list initialization, or design-wise, if I should somehow avoid this scenario)?


Solution

  • Consider this three classes:

    #include <vector>
    #include <initializer_list>
    
    struct aggregate {
        int a,b,c,d;
    };
    struct non_aggregate {
        int a,b,c,d;
        non_aggregate(std::vector<int>) {}
    };
    struct init_list_constr {
        int a,b,c,d;
        init_list_constr(std::initializer_list<int>) {}
    };
    
    int main() {
        aggregate a = {1,2,3,4};
        //non_aggregate b = {1,2,3,4}; // error
        init_list_constr c = {1,2,3,4};
    }
    

    aggregate is an aggregate because it has no user defined constructor. You can use aggregate initialization: aggregate a = {1,2,3,4};. non_aggregate is not an aggregate because it has a user defined constructor and you cannot use aggregate initialization.

    I suggest you to provide a std::initializer_list constructor which makes aggregate initialization possible also with a user defined constructor.

    For details I refer you to https://en.cppreference.com/w/cpp/language/aggregate_initialization