As an addendum to this question, what is going on here:
#include <string>
using namespace std;
struct A {
string s;
};
int main() {
A a = {0};
}
Obviously, you can’t set a std::string to zero. Can someone provide an explanation (backed with references to the C++ Standard, please) about what is actually supposed to happen here? And then explain for example):
int main() {
A a = {42};
}
Are either of these well-defined?
Once again an embarrassing question for me – I always give my structs constructors, so the issue has never arisen before.
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
you are basically copy-initializing
a.swith0, i.e. fora.sit is semantically equivalent toThe above compiles because
std::stringis convertible from aconst char *pointer. (And it is undefined behavior, since null pointer is not a valid argument in this case.)Your
42version will not compile for the very same reason thewill not compile.
42is not a null pointer constant, andstd::stringhas no means for conversion frominttype.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::stringis not an aggregate, but it doesn’t change anything for yourA.Ais still an aggregate.