使用聚合初始化和成员初始化程序初始化结构

用户16

考虑以下示例:

#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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章