考虑以下示例:
#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;
}
定义结构ABC而没有id clang 3.x和gcc 4.8.x的默认值时编译代码没有问题。但是,在为&#34; id&#34;添加默认参数后我收到了流动的错误消息:
13 : error: no matching constructor for initialization of 'ABC'
ABC abc{"hi", 0};
^ ~~~~~~~~~
4 : note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
struct ABC
^
4 : note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
4 : note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided
1 error generated.
Compilation failed
从技术角度来看,当我使用默认参数定义id时会发生什么,为什么在这种情况下不能进行聚合初始化?我是否隐式定义了某种构造函数?
答案 0 :(得分:29)
Bjarne Stroustrup和Richard Smith提出了一个关于聚合初始化和成员初始化器无法协同工作的问题。
聚合的定义在C ++ 11&amp ;; C ++ 14标准。
从C ++ 11标准草案n3337第8.5.1节中说:
聚合是一个没有用户提供的数组或类(第9条) 构造函数(12.1), 没有用于非静态的大括号或等于初始化器 数据成员 (9.2),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)。
但C ++ 14标准草案n3797第8.5.1节说:
聚合是一个没有用户提供的数组或类(第9条) 构造函数(12.1),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)。
因此,当您在C ++ 11中的数据成员id
中使用类成员初始化程序( 即相等的初始化程序 )时,它不再是聚合&安培;您无法编写ABC abc{"hi", 0};
来初始化struct ABC.
因为它之后不再是聚合类型。但是你的代码在C ++ 14中是有效的。 (参见现场演示here)。
答案 1 :(得分:-1)
在c ++中,struct和类是相同的,除了结构具有默认的公共成员和类具有私有。如果你想使用初始值,我认为你必须编写一个构造函数或使用这样的东西:
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;
}