如何就地初始化数组?

2024-03-29

如何在不复制或移动构造临时元素的情况下初始化数组?当元素有明确的deleted 复制或移动构造函数,仅当元素具有默认构造函数或具有所有默认参数的构造函数时,我才能初始化数组,并且执行以下操作之一:(a) 明确声明数组,(b) 直接初始化和零初始化数组,或 (c) 复制初始化和零初始化数组。直接(但不是零)初始化和复制(但不是零)初始化都无法编译。

struct Foo
{
    Foo(int n = 5) : num(n) {}
    Foo(const Foo&) = delete;
    //Foo(Foo&&) = delete;  // <-- gives same effect
    int num;
};

int main()
{
    // Resultant arrays for 'a1', 'a2', and 'a3' are two
    // 'Foo' elements each with 'num' values of '5':

    Foo a1[2];          // plain declaration
    Foo a2[2] {};       // direct initialization and zero initialization
    Foo a3[2] = {};     // copy initialization and zero initialization
    Foo a4[2] {5, 5};   // direct initialization -> ERROR
    Foo a5[2] = {5, 5}; // copy initialization   -> ERROR
}
  1. 这 3 种方式是only在不复制/移动临时元素的情况下初始化数组的方法?
  2. Do a1, a2, and a3算作初始化吗?例如a1是一个声明,但它的元素获得初始值(尽管是默认值)。
  3. 其中有错误吗?我用 C++14 标志做了这个 GCC 6.3.0。
  4. 如果仍然属于以下范畴,为什么复制初始化与零初始化相结合会起作用?copy初始化?
  5. 一般来说,有all带大括号的数组初始化只是临时元素的构造(除非在没有删除复制或移动构造函数时被省略(或者省略不适用于数组?)),然后是每个元素的复制、移动或复制和移动构造的混合?

代码声明Foo a2[2];声明一个数组。初始化数组的唯一方法是通过列表初始化(即用大括号括起来的零个或多个元素的列表),并且该行为由标题为“标准”的部分描述聚合初始化 http://en.cppreference.com/w/cpp/language/aggregate_initialization。 (期限总计的指的是数组和满足特定条件的类)。

在聚合初始化中,存在=没有什么区别。它的基本定义在C++14 [dcl.init.aggr]/2中:

当聚合由初始值设定项列表初始化时,如 8.5.4 中所指定,初始值设定项列表的元素将被视为聚合成员的初始值设定项,按递增的下标或成员顺序。每个成员都是从相应的初始化子句复制初始化的。

另外,/7:

如果列表中的初始化子句少于聚合中的成员,则每个未显式初始化的成员应从其大括号或等于初始化器初始化,或者如果没有大括号或等于初始化器,则应从其大括号或等于初始化器初始化。 初始化器,来自空初始化器列表(8.5.4)。

您可以从中看到,复制初始化始终用于每个提供的初始值设定项。因此,当初始值设定项是表达式时,该类必须存在可访问的复制/移动构造函数。

但是(按照 Anty 的建议)您可以将初始化器设置为另一个列表。使用列表的复制初始化称为复制列表初始化:

Foo a6[2] = {{6}, {6}};

当一个人Foo是列表初始化的,它不是聚合初始化(因为Foo不是一个集合)。因此,规则与上面讨论的规则不同。非聚合类的复制列表初始化属于列表初始化,在 [dcl.init.list]/3.4 中,它指定Foo使用重载解析将列表中的初始值设定项与构造函数参数进行匹配。在这个阶段Foo(int)将选择构造函数,这意味着不需要复制构造函数。


为了完整起见,我将提到核选择 https://stackoverflow.com/questions/28187732/placement-new-in-stdaligned-storage:

typename std::aligned_storage< sizeof(Foo), alignof(Foo) >::type buf[2];
::new ((void *)::std::addressof(buf[0])) Foo(5);
::new ((void *)::std::addressof(buf[1])) Foo(5);
Foo *a7 = reinterpret_cast<Foo *>(buf);

// ...
a7[0].~Foo();
a7[1].~Foo();

显然,当您无法通过任何其他方式实现目标时,这是最后的手段。


注1:以上适用于C++14。在 C++17 中,我相信所谓的“保证复制省略”会将复制初始化更改为实际上不需要复制/移动构造函数。一旦标准发布,我希望更新这个答案。草案中还对聚合初始化进行了一些修改。

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

如何就地初始化数组? 的相关文章

随机推荐

  • xyplot 中的多个 ablines

    我有一个 长 数据框定义为 q lt data frame Indicator Code factor Year numeric Value numeric 我试图在单个 xyplot 中绘制每个不同年份的值作为年份的函数Indicator
  • PHP 包含最佳实践问题

    我一直在学习 PHP 语法并进行练习 我有 NET 背景 因此母版页总是让我在处理页眉和页脚时变得非常简单 到目前为止 我有一个 mainHeader php 和 mainFooter php 其中有我的头部菜单和页脚 html 我创建了一
  • Android 和 iOS 上的 Open Graph SMS 丰富消息

    我正在尝试利用带有开放图元标记的富文本消息 因此 我已将元标记包含在我的网站头部中 并且它通过了所有 Facebook 调试和 iOS API 验证工具 然而 当我通过短信将链接发送给 Android 或 iOS 上的人时 它通常不起作用
  • 获取 Facebook 页面帖子

    我编写了一些 JavaScript 来获取 Facebook 页面上的所有帖子 我这样做的 URL 是这样的 http graph facebook com cocacola feed limit 5 callback facebookRe
  • C# 嵌入vlc控件

    我尝试将 VLC 嵌入到我的 WPF 项目中 我已经注册了 axvlc dll 还下载了 VLC nightly build 版本 2 2 2 System Windows Markup XamlParseException 类型的第一次机
  • Netbeans 删除内置类?

    我有一个 NetBeans 项目 其中有很多类 过去三周我一直在研究这个项目 今天才开始遇到这个问题 单击 NetBeans 中的 运行主项目 按钮时 我看到以下错误 Exception in thread main java lang N
  • 在x86汇编中,为imul使用两个单独的寄存器是否更好?

    我想知道 主要是出于好奇 使用相同的寄存器进行操作是否比使用两个更好 考虑到性能和 或其他问题 什么会更好 mov rbx rcx imul rcx rcx or mov rbx rcx imul rbx rcx 任何有关如何对此进行基准测
  • 适用于 Windows 安装的 GitHub

    安装 GitHub for Windows 时 如何解决此错误 尝试下载时发生错误 http github windows s3 amazonaws com GitHub application http github windows s3
  • 以下是在 Python Mechanize 中按下提交按钮的结果

    所以我有一个经过身份验证的网站 我想通过 mechanize 模块访问该网站 我可以登录 然后转到我想要的页面 但是 由于该页面识别出 mechanize 未启用 javascript 因此它希望我单击提交按钮以重定向到网站的非 javas
  • 如何在 Mockito 中模拟 instanceof

    我有一段代码 我想用 Mockito 测试一下 mockedClass instanceof SampleInterface The mockedClass被嘲笑的抽象类 MockedClass 以及SampleInterface是一个接口
  • 消除 Javascript 中的按键延迟

    我有以下问题 我正在尝试编写一个 Javascript 游戏 并且角色由箭头键控制 问题是 当一个人按住按键时 在触发第一个按键之间有一个短暂的延迟keypress以及重复的keypress 另外 当按下 向右箭头键 并保持按下状态 然后按
  • 使用基于函数的视图更新视图

    如何将对象传递到模型表单中以在呈现页面时预填充字段 我想做一些类似于 Django UpdateView 基于类的视图中的构建 但使用基于函数的视图 只需从模型中获取对象并将该对象作为实例传递给表单即可 然后将表单传递给模板 像下面的例子一
  • 使用 Flexjson 将 JSON 列表反序列化为对象列表

    我正在尝试反序列化以下 json books id 1 name book 1 id 2 name book 2 进入列表 之前用这个 json 工作过 id 1 name book 1 id 2 name book 2 使用此代码 Lis
  • data.table 将 NA 替换为多列的均值和 id

    如果我有以下数据表 dat lt data table id c 1 1 1 1 2 2 2 2 var1 c NA 1 2 2 1 1 2 2 var2 c 4 4 4 4 5 5 NA 4 var3 c 4 4 4 NA 5 5 5 4
  • setTimeout 函数中未定义的 JavaScript 变量

    我有以下代码 for var i 0 i lt markers length i var lat markers i 0 var lng markers i 1 var img markers i 2 var info markers i
  • 重命名 Azure Active Directory

    目前 我有一个与我在 Azure 平台工作的公司的一组订阅关联的 Active Directory 但是 默认目录 AD 位于域上forenamesurnamehotmailco where forenamesurname是一名不再在这里工
  • jquery iframe跨域动态高度

    仅使用 jquery 且没有庞大的插件 这是否可能 我知道有很多插件和替代品 我正在寻找最短 最强大和最干净的 最好依赖jquery 这里有基本的 jsfiddle 来尝试你的想法 http jsfiddle net 3vPJd http
  • 有没有办法将这个 PHP 放入数组并简化它?

    以下代码加载在指定文件夹 单独定义 中找到的所有 php 文件 有没有办法将其放入数组中以简化代码 只有几个变量发生变化 但本质上代码会重复多次 The General Files the general opendir FRAMEWORK
  • 登录和会话 PHP

    我在检查会话时遇到一些问题 要访问页面 我需要激活会话 登录流程 Connect to mysql server require reservation connect php Function to sanitize values rec
  • 如何就地初始化数组?

    如何在不复制或移动构造临时元素的情况下初始化数组 当元素有明确的deleted 复制或移动构造函数 仅当元素具有默认构造函数或具有所有默认参数的构造函数时 我才能初始化数组 并且执行以下操作之一 a 明确声明数组 b 直接初始化和零初始化数