作为这个问题的补充,这里发生了什么:
#include <string>
using namespace std;
struct A {
    string s;
};
int main() {
    A a = {0};
}
显然,你不能将std :: string设置为零.有人可以提供一个解释(请参考C++标准,请参考)这里应该发生什么?然后解释一下):
int main() {
    A a = {42};
}
这些都是明确界定的吗?
对我来说又一个令人尴尬的问题 - 我总是给我的结构构造者,所以这个问题从未出现过.
AnT*_*AnT 29
您的结构是一个聚合,因此聚合初始化的普通规则适用于它.该过程在8.5.1中描述.基本上整个8.5.1专用于它,所以我没有看到在这里复制整个事情的原因.一般的想法几乎与C中的一样,只适用于C++:你从右边拿一个初始化器,你从左边拿一个成员,然后用初始化器初始化成员.根据8.5/12,这应该是复制初始化.
当你这样做
A a = { 0 };
你基本上复制初始化a.s用0,即对于a.s它在语义上等同于
string s = 0;
以上编译因为std::string可以从const char *指针转换.(并且它是未定义的行为,因为在这种情况下空指针不是有效参数.)
你的42版本不会因为同样的原因而编译
string s = 42;
不会编译.42不是空指针常量,并且std::string无法从int类型转换.
PS以防万一:请注意,C++ 中聚合的定义不是递归的(例如,与POD的定义相反).std::string不是聚合,但它不会改变你的任何东西A.A仍然是一个聚合.
8.5.1/12"聚合"说:
使用初始化程序列表中的初始化程序初始化聚合成员时,将考虑所有隐式类型转换(第4节).
所以
A a = {0};
将使用NULL进行初始化char*(如AndreyT和Johannes所示),以及
A a = {42};
将在编译时失败,因为没有隐式转换将与std::string构造函数匹配.