From C++11 and above, I can construct a class with list initialization std::vector<int> foo{1,2,3} or copy list-initialization with std::vector<int> foo = {1,2,3}. Assuming I have a class as follows
class Bar {
};
class Event{
public:
int time;
Bar* ptr;
Event() = default;
Event(int t, Bar* p):time(t),ptr(p){};
};
I don't know why the following code compiles, given that I have not overloaded any = , neither defined any specific constructor except the two in the Event class.
Event e1 = {1, nullptr}; // compiles, why e1 can be assigned a value with {} given it is not an aggregate type
// --------------------
std::map<int, Event> mp;
mp[1] = {1, nullptr}; // compiles, same confusion, why I can use curly braces to assign?
Seems like you are confusing the idea between List initialization and Aggregate initialization.
While aggregate initialization is a form of list initialization, list initialization often refers to the initialization that uses std::initializer_list, which is introduced in C++11.
List initialization can often be used to simplify the creation of a member container. To create a constructor that uses std::initializer_list, you would do:
struct Foo {
std::vector<int> vec;
Foo(std::initializer_list<int> li)
: vec(li)
{}
};
And now you can create a Foo with: Foo foo{1,2,3,4,5} or Foo foo = {1,2,3,4,5}.
std::initializer_list also has the begin() and end() iterator, so you can access the member through for-loops if needed. However, do notice that it does not have a bracket accessor operator[], and it must be monotype, which means it is not applicable in your case.
Instead what you are looking for is aggregate initialization. To enable aggregate initialization, all you need is to make sure all members are public visible, and you do not have a user declared constructor:
class Event{
public:
int time;
Bar* ptr;
};
Now you can aggregate initialize a Event with the syntax you wanted:
Event e1 = {1, nullptr};
Event e2{1, nullptr};
Optionally, you can provide default values for each member:
class Event{
public:
int time = 0;
Bar* ptr = nullptr;
};
int main()
{
Event e1; // e1.time defaulted to 0, e1.ptr defaulted to nullptr
Event e2{5}; // e2.ptr defaulted to nullptr
}
Without the default value, doing Event e1; could make e1.time and e1.ptr be potentially undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With