【问题标题】:Array inside Struct wont copy correctly结构内的数组不会正确复制
【发布时间】:2022-01-02 22:07:28
【问题描述】:

想知道是否有人可以帮助我,我的代码中有这个结构

struct Gate {
  int output[9];
};

我有一个该结构的向量,但是推送到通常会创建副本的向量会中断,因为它只是一个浅拷贝,而且我的结构有一个数组 所以我尝试通过创建自定义复制构造函数来解决这个问题。

struct Gate {
    int output[9];
    Gate(const Gate &old){
        copy(old.output, old.output + 9, output);
    }
};

但现在我的初始化程序不再工作了,因为他们正在尝试使用这个复制构造函数

Gate alwaysFirst{{0,0,0,1,1,1,2,2,2}};
Gate alwaysSecond{{0,1,2,0,1,2,0,1,2}};
universal_gate_finder.cpp:39:41: error: cannot convert '<brace-enclosed initializer list>' to 'const Gate&'
   39 |     Gate alwaysFirst{{0,0,0,1,1,1,2,2,2}};
      |  

有人知道解决这个问题的方法吗?

【问题讨论】:

  • 我相信这种类型的对象可以正确复制,而不需要显式的复制构造函数。究竟是什么让你相信事实并非如此?
  • "推送到通常会创建副本的向量会损坏,因为它只是一个浅副本" - struct 还需要什么?默认的复制构造函数会复制 output 就好了。
  • 这里是代码:pastebin.com/1PWdJSG4 我在第 53 行创建 Gate 对象,并将它们复制到第 62 和 67 行的向量中。我在第 58 行检查以确保没有出于任何原因,数组值大于 2。在第 55 行我检查它是否仍然小于 2,我得到的错误是在第 55 行,这意味着在我将它们复制到向量后值正在发生变化。
  • 请在此处提供minimal reproducible example
  • 除非我做错了什么(可能在第 49 行和第 57 行之间,我认为该错误与内存有关。

标签: c++ arrays struct


【解决方案1】:
Gate alwaysFirst{{0,0,0,1,1,1,2,2,2}};
Gate alwaysSecond{{0,1,2,0,1,2,0,1,2}};

这些行使用聚合初始化,这只能在聚合上使用,它不能有用户声明的构造函数。

通过声明自定义复制构造函数,您的类型不再是聚合的。

您可以将聚合初始化替换为 std::initializer_list 构造函数或通过引用获取数组的构造函数,这两者都会重新启用该语法(或多或少)。

但是,不需要声明复制构造函数。隐式复制构造函数已经通过逐元素复制构造从源对象构造了数组成员。

您的替换改为使用复制分配,这与直接复制构造元素相比没有任何好处。

声明复制构造函数也会禁用隐式移动构造函数,这是一种额外的悲观。

【讨论】:

  • 谢谢你的详细回复,我不知道这个。在这种情况下,您知道为什么我的数组没有使用默认构造函数正确复制吗?我在最初帖子的评论中列出了详细信息。另外, initalizer_list 构造函数的外观如何,我在网上找不到任何东西。
  • @ConorOMalley 您应该在问题本身中发布一个最小的可重现示例。您代码中的问题与Gate 的数组成员无关。但是现在有点晚了,因为您的无关问题已经有了答案。
  • @ConorOMalley 将元素插入向量中会使所有迭代器、指针和对向量元素的引用无效。所以在遍历向量时这样做是个坏主意。
  • 兄弟,非常感谢你,你是个天才,就是这样,我的指针被搞砸了,因为我把东西推到同一个向量上,谢谢你。
【解决方案2】:

你试过struct Gate { std::array&lt;int, 9&gt; output; };吗?
Compiler Explorer

【讨论】:

  • 我仍然收到我帖子评论中描述的相同错误,突然间数组中的一个元素是一个疯狂的高数字
  • 好的,我在您帖子的 cmets 中看到了您的链接。停止使用指针。对bool[]std::array 使用std::bitset,而不是C 样式的数组。然后,您可以使用set(getHash(alwaysFirst)) 设置位集中的位,其中getHashstatic std::size_t getHash(std::array&lt;int, 9&gt; const&amp;) noexcept;。是的,您可能正在取消引用一些超出限制的内存,不,我不能告诉您它发生在哪里。
猜你喜欢
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 2015-05-08
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 2013-02-24
  • 2021-05-04
相关资源
最近更新 更多