Is such code with the aggregate initialization a valid C++ program?
#include <iostream>
#include <numeric>
struct Sheet {
const int c[2]{};
const int sum = std::accumulate(std::begin(c), std::end(c), 0);
};
int main() {
Sheet sheet0;
Sheet sheet1{{10}};
Sheet sheet2{{10, 20}};
std::cout << sheet0.sum << "\n";
std::cout << sheet1.sum << "\n";
std::cout << sheet2.sum << "\n";
}
// Outputs:
// 0
// 10
// 30
This is a struct with the Excel sheet like behavior: a user initializes cells with some values, if a user does not initialize sum
then it gets the computed sum of the cell values.
I am not sure that inline member initialization and not zero initialization happens at skipped members in aggregate initialization.
I expected that the statement
Sheet sheet2{{10, 20}};
would be the same as
Sheet sheet2{{10, 20}, {}};
and output 0, but my program runs showed that they result in different outputs 30 and 0.
For Sheet sheet2{{10, 20}};
, the data member sum
will be initialized by its default member initializer. It's not same as Sheet sheet2{{10, 20}, {}};
where sum
will be initialized by {}
.
For a non-union aggregate, each element that is not an explicitly initialized element is initialized as follows:
If the element has a default member initializer, the element is initialized from that initializer. (since C++11)
Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list.
Otherwise, the program is ill-formed.
struct S { int a; const char* b; int c; int d = b[a]; }; // initializes ss.a with 1, // ss.b with "asdf", // ss.c with the value of an expression of the form int{} (that is, 0), // and ss.d with the value of ss.b[ss.a] (that is, 's') S ss = {1, "asdf"};
In detail, for Sheet sheet0;
, data member c
and sum
will be initialized by their default member initializers. The 2 elements of c
will be zero.
For Sheet sheet1{{10}};
, c
will be initialized by {10}
, sum
will be initialized by its default member initializer. As {10}
contains only 1 initializer which is less than the number of members of c
as 2, the 1st element of c
will be 10
and the 2nd one will be zero.
For Sheet sheet2{{10, 20}};
, c
will be initialized by {10, 20}
, sum
will be initialized by its default member initializer. As the effect the 1st element of c
will be 10
and the 2nd one will be 20
.