使用聚合初始化和成员初始值设定项初始化结构

时间:2016-03-09 12:10:37

标签: 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.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时会发生什么,为什么在这种情况下不能进行聚合初始化?我是否隐式定义了某种构造函数?

2 个答案:

答案 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;
}