Wer*_*mus 6 c++ initialization language-lawyer aggregate-initialization c++11
鉴于下面的示例,我很惊讶地发现尽管显式删除了默认构造函数(或者默认为此),但仍然可以进行聚合初始化.
#include <iostream>
struct DefaultPrivate
{
const int n_;
static const DefaultPrivate& create();
private:
DefaultPrivate() = delete;
};
const DefaultPrivate& DefaultPrivate::create()
{
static DefaultPrivate result{10};
return result;
}
int main() {
DefaultPrivate x; //Fails
DefaultPrivate y{10};//Works
return 0;
}
Run Code Online (Sandbox Code Playgroud)
私有默认(或删除)构造与聚合初始化之间的关系是否未在标准中指定?
GCC 6.3和VCC 2017就属于这种情况
我问这个问题的原因是,我希望更改对默认构造函数的访问会阻止公共聚合初始化
从 C++11 开始,对于列表初始化,
如果
T是聚合类型,则执行聚合初始化。
在 C++11 中,聚合是以下类型之一:
...
类类型(通常,结构或联合),具有
...
没有用户提供的
, inherited, or explicit (since C++17)构造函数(explicitly defaulted or deleted constructors are allowed) (since C++11)...
这意味着从 C++11 开始,显式删除构造函数的类仍然被视为聚合类型,然后允许聚合初始化。
效果是:
每个
direct public base, (since C++17)数组元素或非静态类成员,按照类定义中数组下标/出现的顺序,从初始值设定项列表的相应子句中复制初始化。
注意,对于DefaultPrivate y{10};在上述过程中,默认的构造函数将根本不被考虑,那么,它的声明的事实delete和private不会的事情。
BTW:对于执行DefaultPrivate x; 默认初始化,
如果
T是non-POD (until C++11)类类型,则考虑构造函数并针对空参数列表进行重载决议。调用选定的构造函数(默认构造函数之一)为新对象提供初始值;
所以尝试使用默认构造函数但它被delete编辑然后编译失败。
如果您使用聚合初始化,例如DefaultPrivate x{};,代码也可以正常工作;并且n_将值初始化(然后零初始化)为0。
| 归档时间: |
|
| 查看次数: |
508 次 |
| 最近记录: |