So I've read here: https://stackoverflow.com/a/598150/2642059 that this is illegal:
foo(i++, i++);
But I believe that's because there is not a forced sequence, which I understand is the case for Initializer Lists. So is this legal code?
const int foo[] = { i++, i++ };
You must initialize the following cases with an initializer list: base classes with no default constructors, reference data members, non-static const data members, or a class type which contains a constant data member.
Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.
Const member variables must be initialized. A member initialization list can also be used to initialize members that are classes. When variable b is constructed, the B(int) constructor is called with value 5. Before the body of the constructor executes, m_a is initialized, calling the A(int) constructor with value 4.
Initialization lists allow you to choose which constructor is called and what arguments that constructor receives. If you have a reference or a const field, or if one of the classes used does not have a default constructor, you must use an initialization list.
Yes, the order of the evaluation of initializer-clauses is guaranteed in braced-init-list.
From the standard, §11.6.4/4 List-initialization [dcl.init.list]:
(emphasis mine)
Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions, are evaluated in the order in which they appear. That is, every value computation and side effect associated with a given initializer-clause is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list. [ Note: This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the initializer-list are interpreted as arguments of a constructor call, even though ordinarily there are no sequencing constraints on the arguments of a call. — end note ]
From cppreference.com:
Every initializer clause is sequenced before any initializer clause that follows it in the braced-init-list. This is in contrast with the arguments of a function call expression, which are unsequenced.
Example for the note of the standard,
struct A { A(int, int) {} };
...
int i = 0;
A a1(i++, i++); // used as the arguments of the constructor; unsequenced
A a2{i++, i++}; // used as the arguments of the constructor; sequenced, within the initializer-list of a braced-init-list
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