聚合初始化中 mem-initializer 的有效性和/或生命周期扩展

2023-12-28

CWG 1815asked http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1815(有少量修改):

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 打算#3表现得像#2;也就是说,结构良好,并且执行临时对象的生命周期扩展b3.a绑定。但在下一次 ISO 会议(拉珀斯维尔,2014 年 6 月)上,决议CWG 1696 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1696被通过,表面上解决了 CWG 1815,但adopting https://github.com/cplusplus/draft/commit/c93a904986ca0cdf9cd02bc5aafc0da258d6a47b语言似乎使#3不规范的 https://eel.is/c++draft/class.base.init#11:

11 - 从默认成员初始值设定项绑定到引用成员的临时表达式格式不正确。

然而,该子句下面的示例不考虑聚合初始化(如 CWG 1815 中所示),而仅考虑构造函数的初始化;具体来说,定义为 defaulted 的默认构造函数:

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

因此,虽然措辞看起来很清楚,但似乎也违背了委员会的意图,这可能是认为措辞有缺陷的理由。

从实施实践来看,我们可以see that https://godbolt.org/z/K9rGsP存在相当大的差异:

gcc clang MSVC ICC
#1 ❌ destroy ✅ reject ☠️ leak ❌ destroy
#2 ✅ extend ✅ extend ✅ extend ✅ extend
#3 ❌ extend ❌ extend ❌ extend ❌ destroy

(这里,“销毁”意味着临时对象在声明结束时被销毁,即不延长生命周期。✅ 表示符合,❌ 不符合,☠️ 明显的缺陷。)但是,除了 ICC 之外,编译器还同意延长生命周期在#3,与目前的措辞相反。奇怪的是,尽管执行了生命周期延长,Clangwarns它无法这样做,表明开发人员认为在这种情况下标准需要延长生命周期:

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

Question

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


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

聚合初始化中 mem-initializer 的有效性和/或生命周期扩展 的相关文章

  • 无法对 ContainsGenericParameters 为 true 的类型或方法执行后期绑定操作

    我有一个适用于所有实体的扩展 public static class EntityBaseExtensions public static T Clone
  • 如何在C编程中获取当前时间(以毫秒为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 如何使用 ANSI C 测量以毫秒为单位的时间 https stackoverflow com questions 361363 how to measure time in milliseconds
  • 使用 QTextCursor 选择一段文本

    使用 Qt 框架选择文本片段时遇到问题 例如 如果我有这个文件 没有时间休息 我想选择 ime for r 并从文档中删除这段文本 我应该如何使用 QTextCursor 来做到这一点 这是我的代码 QTextCursor cursor n
  • ZedGraph 缩放和调整大小

    当我绘制图形 放大和缩小并重新绘制图形时 图形的位置不会改变 我想要做的是 每当重新绘制数据时 视图都会更改以查看所有图形数据 如果您在重绘之前放大或缩小 这似乎会被禁用 Thanks 设置属性 IsZoomOnMouseCenter对于控
  • 当“”可以分配给std::string时,为什么有“clear”方法?

    一个可以用string clear函数清空字符串 也可以使用空双引号 来执行此操作 有什么不同 当您分配一个空字符串时 编译器必须在数据部分存储一个空的 C 字符串 并创建代码以将指向它的指针传递给赋值运算符 然后 赋值运算符必须从数据部分
  • C++17 中带有 noexcept 的 std::function

    在 C 17 中noexcept 已添加到类型系统中 http www open std org jtc1 sc22 wg21 docs papers 2015 p0012r1 html void r1 void f noexcept f
  • 优化对绑定到 DataGridView 的 DataTable 的更新

    我的应用程序中有一个显示一些数据的表单 当我第一次显示表单时 我将一些数据加载到 DataTable 中 然后将 DataTable 绑定到 DataGridView 我还启动了一个异步方法来执行一些较慢的数据库查询 当这些慢查询完成时 我
  • 有哪些 API 可在 Windows 中使用 C# 配置扬声器设置?

    我环顾了很多不同的地方 但似乎找不到一个简单的方法来做到这一点 我在 Windows 7 中有多个声卡 并使用 HDMI 将声音输出到我的 AVR 放大器 我遇到的问题是 当放大器关闭时 它会导致窗口丢失扬声器配置 所以我想做的是编写一个小
  • .NET 中 IEqualityComparer 中 GetHashCode 的作用是什么?

    我试图了解 IEqualityComparer 接口的 GetHashCode 方法的作用 下面的例子取自MSDN using System using System Collections Generic class Example st
  • 使用 for 循环创建链表

    这是我的结构 struct ListItem int data struct ListItem next 假设链表的第一个节点的 data 0 我想编写一个 for 循环来创建大小为 5 的链表 但我不知道如何工作 我尝试了以下方法 int
  • 锁定文件的一个块

    我有一个大小为 192k 的文件 我想锁定文件的中间部分 例如 我想用 c 锁定文件的 64k 128k 知道如何锁定文件的那部分吗 你需要使用锁定文件Ex http msdn microsoft com en us library win
  • 如何忽略搜索条件中的空属性

    我有一个不好的要求要做 无论如何 我必须在我的应用程序中实现它 我有一个Track class public class Track public string Name get set public string City get set
  • 表单.位置不起作用

    我之前问过这个问题 以为我已经解决了 但它仍然不起作用 Form Show 稍微移动表单位置 https stackoverflow com questions 1214014 form show moves form position s
  • C# Linq 可以做组合数学吗?

    我有这个数据结构 class Product public string Name get set public int Count get set var list new List
  • 如何从句柄确定进程是 32 位还是 64 位?

    如何从使用 OpenProcess 获取的进程句柄中获取信息 无论进程是 32 位还是 64 位 是的 IsWow64Process 毫无用处 令人烦恼 它的真正意思是 启用了 32 位模拟 如果您在 32 位操作系统上运行 则返回 fal
  • 派生类的聚合初始化

    以下代码无法使用 Visual Studio2017 或在线 GDB 进行编译 我期望它能够编译 因为迭代器只是一个具有类型的类 并且它是从公共继承的 这是不允许的还是在 VS2017 中不起作用 template
  • 序列化时如何跳过 xml 声明?

    我正在尝试输出一个没有 xml 头的 xml 文件 例如 我试过 Type t obj GetType XmlSerializer xs new XmlSerializer t XmlWriter xw XmlWriter Create c
  • C# 记录类型:记录子类之间的相等比较

    给定父记录类型 public record Foo string Value 和两个记录子类Bar and Bee我想知道是否可以实施Equals在基类中 因此 Foo Bar 或 Bee 的实例都被考虑equal基于Value 两者都与E
  • 如何通过Task.ContinueWith创建传递?

    我想在原始任务结束时添加一个任务 但想保留原始结果和类型 附加任务仅用于记录目的 例如写入控制台等 例如 Task Run gt DateTime Now Hour gt 12 Hey throw new Exception Continu
  • “保留供任何使用”是什么意思?

    注意 这是一个c questions tagged c问题 虽然我补充说c questions tagged c 2b 2b如果某些 C 专家可以提供 C 使用与 C 不同的措辞的基本原理或历史原因 在 C 标准库规范中 我们有这个规范文本

随机推荐