我有一个类似于这样的代码:
class AClass {
public:
struct AStruct { };
AClass(){}
private:
const AStruct m_struct;
};
int main() {
AClass a;
}
Run Code Online (Sandbox Code Playgroud)
error: constructor for 'AClass' must explicitly initialize
the const member 'm_struct'
Run Code Online (Sandbox Code Playgroud)
如果我指定一个C++ 11默认构造函数struct AStruct,我会得到同样的错误:
struct AStruct {
AStruct() = default;
};
Run Code Online (Sandbox Code Playgroud)
但是,这可以通过编写一个空体的构造函数来解决:
struct AStruct {
AStruct(){} // fixed
};
Run Code Online (Sandbox Code Playgroud)
为什么我需要指定一个空构造函数?它是不是通过结构的公共访问自动创建的?
为什么C++ 11默认构造函数不解决问题?
chr*_*ris 27
来自§8.5[dcl.init]/7:
如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型.
default的默认构造函数AClass初始化const成员(参见下文),以便该成员必须具有用户提供的默认构造函数.使用= default不会导致用户提供的默认构造函数,如§8.4.2[dcl.fct.def.default]/4中所示:
如果函数是用户声明的,并且在第一个声明中未明确默认或删除,则用户提供该函数.
根据§12.6.2[class.base.init]/8默认初始化该成员:
在非委托构造函数中,如果给定的非静态数据成员或基类未由mem-initializer-id指定(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer)然后,实体不是抽象类(10.4)的虚基类
- 如果实体是具有大括号或等于初始化程序的非静态数据成员,则按照8.5中的规定初始化该实体;
- 否则,如果实体是匿名联合或变体成员(9.5),则不执行初始化;
- 否则,实体默认初始化(8.5).
Yak*_*ont 17
从@ chris的答案中被盗我们有这一段:§8.5[dcl.init]/7:
如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型.
然后我们可以构建一个完全荒谬的案例来说明这个限制:
struct Foo {};
int main() {
const Foo f;
}
Run Code Online (Sandbox Code Playgroud)
根据标准的规定,它无法在clang中编译.您的代码就是这样,但作为另一个类/结构的成员变量.
我们甚至可以这样做:
struct Foo {int x = 3;};
int main() {
const Foo f;
}
Run Code Online (Sandbox Code Playgroud)
所有数据显然都已初始化.最后一个例子让我相信这是标准中的缺陷.
这个想法可能与未初始化的POD类型有关const,但是措辞阻止了与之无关的代码.现代C++中的默认构造函数通常都足够好,并且强制Foo(){}形式很差.
| 归档时间: |
|
| 查看次数: |
2194 次 |
| 最近记录: |