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)?
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