聚合初始化中 mem-initializer 的有效性和/或生命周期延长 问题

问题描述

CWG 1815 asked(稍作修改):

struct A {};
struct B { A&& a = A{}; };
B b1;         // #1
B b2{A{}};    // #2
B b3{};       // #3

[...] #2 是聚合初始化,它将 B::a 绑定到 b2 的初始化程序中的临时变量,从而将其生命周期延长到 b2 的生命周期。 #3 是聚合初始化,但不清楚 B::a 的非静态数据成员初始化器中的临时生命周期是否应该像 #2 那样生命周期延长,像 { {1}}。

根据关于该问题的说明,在 Issaquah (2014-02) CWG 打算使 #1 表现得像 #3;也就是说,格式良好,并执行 #2 绑定到的临时对象的生命周期扩展。但在下一次 ISO 会议(Rapperswil,2014-06 年)上通过了 CWG 1696 的决议,表面上解决了 CWG 1815 但adopting 语言appears to make #3 ill-formed

11 - 绑定到来自默认成员初始值设定项的引用成员的临时表达式格式错误。

然而,紧接在该条款下的示例不考虑聚合初始化(如在 CWG 1815 中),而仅考虑构造函数的初始化;具体来说,一个定义为 defaulted 的默认构造函数:

b3.a

因此,尽管措辞似乎很清楚,但它似乎也与委员会的意图背道而驰,这可能是认为措辞有缺陷的原因。

在实现实践方面,我们可以see that存在相当大的差异:

gcc 叮当声 MSVC ICC
struct A { A() = default; // OK A(int v) : v(v) { } // OK const int& v = 42; // OK }; A a1; // error: ill-formed binding of temporary to reference A a2(1); // OK,unfortunately ❌销毁 ✅拒绝 ☠️泄漏 ❌销毁
#1 ✅ 延长 ✅ 延长 ✅ 延长 ✅ 延长
#2 ❌扩展 ❌扩展 ❌扩展 ❌销毁

(这里,“销毁”表示临时文件在声明结束时被销毁,即不延长生命周期。✅ 表示符合,❌ 不符合,☠️ 一个明显的缺陷。)但是,除了 ICC,编译器同意在 #3 中延长生命周期,与当前的措辞相反。奇怪的是,尽管执行了生命周期延长,Clang 警告它不能这样做,这表明在这种情况下,开发人员认为标准要求延长生命周期:

警告:抱歉,不支持使用默认成员初始值设定项的聚合初始化创建的临时生命周期延长;临时的生命周期将在全表达式结束时结束 [-Wdangling]

问题

鉴于 CWG 表达的意图和实施差异,将当前措辞视为有缺陷并依赖 #3 中发生的生命周期延长是否合理?委员会是否意识到这种差异?是否有可能在近期或中期解决(例如作为 C++20 的 DR)?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...