使用聚合初始化和成员初始化程序初始化结构 [英] Initializing a struct with aggregate initialization and member initializers
问题描述
请考虑以下示例:
#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编译代码没有问题。但是,在为 id添加默认参数之后,我得到了如下错误消息:
When defining the structure ABC without default value for id clang 3.x and gcc 4.8.x compile the code without problems. However, after adding a default argument for "id" I get the flowing error message:
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时会发生什么带有默认参数,为什么在这种情况下无法进行聚合初始化?我是否隐式定义某种构造函数?
From a technical point of view, what is going on when I define id with a default argument and why is aggregate initialization not possible in that case? Do I implicitly define some sort of constructor?
推荐答案
Bjarne Stroustrup和Richard Smith提出了有关聚合初始化和成员初始化器的问题,
Bjarne Stroustrup and Richard Smith raised an issue about aggregate initialization and member-initializers not working together.
聚集的定义在C ++ 11&中略有变化。 C ++ 14标准。
The definition of aggregate is slightly changed in C++11 & C++14 standard.
来自C ++ 11标准草案 n3337 第8.5.1节说:
From the C++11 standard draft n3337 section 8.5.1 says that:
聚集是没有用户提供的
构造函数(12.1)的数组或类(第9条), 没有用于静态
的括号或相等的初始化程序数据成员 (9.2),没有私有或受保护的非静态数据成员
(第11条),没有基类(第10条),也没有虚函数
(10.3) )。
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal- initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
但是C ++ 14标准草案 n3797 第8.5.1节说:
But C++14 standard draft n3797 section 8.5.1 says that:
聚集是没有用户提供的
构造函数(12.1),没有私有或受保护的非静态数据成员
(第11条)的数组或类(第9条)基本类(第10条),并且没有虚拟al函数
(10.3)。
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
因此,当您在类成员初始化器中使用时( i.e。等价的初始化程序 ),对于C ++ 11中的数据成员 id
,它不再保持聚合&您不能编写 ABC abc { hi,0};
来初始化结构ABC。
之后不再保留聚合类型。但是您的代码在C ++ 14中有效。 (请参见实时演示此处)。
So, when you use in class member initializer (i.e. equal initializer) for the data member id
in C++11 it no longer remains aggregate & you can't write ABC abc{"hi", 0};
to initialize a struct ABC.
Because it no longer remains aggregate type after that. But your code is valid in C++14. (See live demo here).
这篇关于使用聚合初始化和成员初始化程序初始化结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!