为什么在const成员结构中需要一个构造函数?

我有一个类似这样的代码:

class AClass { public: struct AStruct { }; AClass(){} private: const AStruct m_struct; }; int main() { AClass a; } 

它会抛出这个编译错误(与Clang LLVM版本5.1):

 error: constructor for 'AClass' must explicitly initialize the const member 'm_struct' 

如果我为struct AStruct指定一个C ++ 11默认的构造struct AStruct ,我得到相同的错误:

  struct AStruct { AStruct() = default; }; 

但是,这是通过写一个空构造的构造函数来解决的:

  struct AStruct { AStruct(){} // fixed }; 

为什么我需要指定一个空的构造函数? 它是不是自动创build公共访问的结构?

为什么C ++ 11的默认构造函数不能解决这个问题?

从§8.5[dcl.init] / 7:

如果程序调用const限定typesT的对象的默认初始化,则T应该是具有用户提供的默认构造函数的类types。

AClass的默认构造函数AClass初始化const成员(见下文),以便成员必须具有用户提供的默认构造函数。 使用= default不会导致用户提供的默认构造函数,可以在§8.4.2[dcl.fct.def.default] / 4中看到:

一个函数是用户提供的,如果它是用户声明的,并且没有明确地默认或删除它的第一个声明。


成员默认初始化每个§12.6.2[class.base.init] / 8:

在非委托构造函数中,如果给定的非静态数据成员或基类不是由mem-initializer-id指定的(包括由于构造函数没有ctor初始值设定项而没有mem-initializer-list的情况)而实体不是抽象类(10.4)的虚拟基类

– 如果实体是一个具有括号或等于初始值设定项的非静态数据成员,则按照8.5中的规定对实体进行初始化;
否则,如果实体是匿名联盟或变体成员(9.5),则不执行初始化;
否则,实体将被默认初始化(8.5)。

从@克里斯的答案窃取我们有这个段落:§8.5[dcl.init] / 7:

如果程序调用const限定typesT的对象的默认初始化,则T应该是具有用户提供的默认构造函数的类types。

然后,我们可以构build一个完全荒谬的案例来说明这个限制:

 struct Foo {}; int main() { const Foo f; } 

它不能按照标准的规定进行编译。 你的代码只是这个,但作为另一个类/结构的成员variables。

我们甚至可以这样做:

 struct Foo {int x = 3;}; int main() { const Foo f; } 

所有的数据都明显初始化。 最后一个例子让我相信这是标准的缺陷。

这个想法可能与PODtypes是未初始化的和consttypes有关,但是措辞会阻止不相关的代码。 现代C ++中的默认构造函数通常不够好,并且强制Foo(){}是不好的forms。