如何解决聚合初始化中 mem-initializer 的有效性和/或生命周期延长 问题
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 举报,一经查实,本站将立刻删除。