C++ 使用聚合初始化和成员初始值设定项初始化结构
考虑以下示例:C++ 使用聚合初始化和成员初始值设定项初始化结构,c++,c++11,constructor,aggregate-initialization,C++,C++11,Constructor,Aggregate Initialization,考虑以下示例: #include <iostream> #include <string> struct ABC { std::string str; unsigned int id ;/* = 0 : error: no matching constructor for initialization of 'ABC'*/ }; int main() { ABC abc{"hi", 0}; std::cout << abc.s
#include <iostream>
#include <string>
struct ABC
{
std::string str;
unsigned int id ;/* = 0 : error: no matching constructor for initialization of 'ABC'*/
};
int main()
{
ABC abc{"hi", 0};
std::cout << abc.str << " " << abc.id << std::endl;
return 0;
}
从技术角度来看,当我用默认参数定义id时会发生什么,为什么在这种情况下不可能进行聚合初始化?我是否在C++结构中隐式地定义了一些构造器?,类是相同的,除了结构有默认的公共成员和类是私有的。如果您想使用初始值,我认为您必须编写一个构造函数或使用类似以下内容:
struct ABC
{
std::string str;
unsigned int id;
} ABC_default = {"init", 0 }; //initial values
int main()
{
ABC abc = ABC_default;
std::cout << abc.str << " " << abc.id << std::endl;
return 0;
}
结构ABC
{
std::字符串str;
无符号整数id;
}ABC_default={“init”,0}//初始值
int main()
{
ABC=ABC\u默认值;
Bjarne Stroustrup和Richard Smith提出了一个关于聚合初始化和成员初始化器不协同工作的问题 在C++11和C++14标准中,聚合的定义略有改变 C++11标准草案第8.5.1节规定: 聚合是没有提供用户的数组或类(第9条) 构造函数(12.1),无大括号或等效项-非静态的初始值设定项 数据成员(9.2),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3) 但是C++14标准草案第8.5.1节规定: 聚合是没有提供用户的数组或类(第9条) 构造函数(12.1),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)
因此,当您在C++11中为数据成员
id
使用类内成员初始值设定项(即相等初始值设定项)时,它不再保持聚合状态&您无法编写ABC{“hi”,0};
来初始化结构ABC.
,因为在这之后它不再保持聚合类型。但是您的代码在C++14中是有效的。(见现场演示).也许我误解了你的问题。你想要的是什么?@erip这很有趣。它在VS 2015中无法编译。只是在VS 2015中发现了这个问题。对于你的编译器来说,它可能是同一个问题。@user3472628:请看我的答案以了解原因。uApplicate,我真的认为这并没有回答OP的问题。这也是错误的,因为NSDM我是五年前加入这门语言的。类似C的语法也无助于回答这个问题。不要听起来像是一张破唱片或其他任何东西,除了“结构和类”不“相同”;struct
引入了一个类,而结构不存在!说“结构和类是相同的”我的意思是,它们是相同的类型,只是关键字不同。谢谢你的回答。这真的很不灵活。有人想多次初始化ABC是什么意思?他必须在ABC的定义中不断指定一种新类型的ABC吗?标准之间的出色比较。+1对于有兴趣查看ABC列表的人。请注意,它不支持聚合的NSDMIs。感谢您指出这一点。这真的很有帮助!+1
struct ABC
{
std::string str;
unsigned int id;
} ABC_default = {"init", 0 }; //initial values
int main()
{
ABC abc = ABC_default;
std::cout << abc.str << " " << abc.id << std::endl;
return 0;
}