As an addendum to this question, what is going on here:
#include
using namespace std;
struct A {
string s;
};
int main() {
A a = {0}
Your struct is an aggregate, so the ordinary rules for aggregate initialization work for it. The process is described in 8.5.1. Basically the whole 8.5.1 is dedicated to it, so I don't see the reason to copy the whole thing here. The general idea is virtually the same it was in C, just adapted to C++: you take an initializer from the right, you take a member from the left and you initialize the member with that initializer. According to 8.5/12, this shall be a copy-initialization.
When you do
A a = { 0 };
you are basically copy-initializing a.s
with 0
, i.e. for a.s
it is semantically equivalent to
string s = 0;
The above compiles because std::string
is convertible from a const char *
pointer. (And it is undefined behavior, since null pointer is not a valid argument in this case.)
Your 42
version will not compile for the very same reason the
string s = 42;
will not compile. 42
is not a null pointer constant, and std::string
has no means for conversion from int
type.
P.S. Just in case: note that the definition of aggregate in C++ is not recursive (as opposed to the definition of POD, for example). std::string
is not an aggregate, but it doesn't change anything for your A
. A
is still an aggregate.