考虑以下示例:
#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 clang 3.x和gcc 4.8.x定义不带默认值的结构ABC时,编译代码不会出现问题。但是,在为“ id”添加默认参数后,我得到了如下错误消息:
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时会发生什么情况,为什么在这种情况下无法进行聚合初始化?我是否隐式定义某种构造函数?
Bjarne Stroustrup和Richard Smith提出了一个关于聚合初始化和成员初始化器无法协同工作的问题。
在C ++ 11和C ++ 14标准中,聚合的定义略有变化。
在C ++ 11标准草案n3337中,第8.5.1节说:
集合是一个数组或一个类(第9条),没有用户提供的构造函数(12.1),没有针对非静态数据成员的大括号或相等初始化器(9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条)和虚拟函数(10.3)。
但是C ++ 14标准草案n3797第8.5.1节说:
聚合是没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11章),没有基类(第10章)和没有虚函数(10.3)的数组或类(第9章)。 )。
因此,当您在C ++ 11中的数据成员中使用类成员初始值设定项(即相等的初始值设定项)时,id
它将不再保持聚合状态,并且您将无法编写ABC abc{"hi", 0};
初始化a的信息,struct ABC.
因为在此之后,它将不再保持聚合类型。但是您的代码在C ++ 14中有效。(请参见此处的现场演示)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句