【问题标题】:Appending QList to QList<QList>将 QList 附加到 QList<QList>
【发布时间】:2018-03-31 04:03:00
【问题描述】:

我对 Qt Qlist 容器有一个有趣的问题。 尝试将 QList 附加到 QList 会使我的迭代器指向内存的未知部分。

QList<int> listSmall;
QList<QList<int>> listBig;

for(int i = 0; i < 3; ++i)
    listSmall.append(i);

for(auto it = listSmall.begin(); it != listSmall.end(); ++it)
    listBig.append(listSmall);

条件it != listSmall.end(); 如果我将小列表附加到大列表,则始终为真。 为什么会这样?

附: STL 列表工作正常。

【问题讨论】:

  • 我对qt一无所知,但请查看此链接,看看您是否能发现它有用stackoverflow.com/questions/41438428/…
  • @Tharushi Geethma 不幸的是,这个问题只是建议使用 stl 算法,但没有说明附加到 QList 有什么问题。
  • 你只要listBig.append(listSmall);一次就可以追加了!?
  • @xander 这不是我在项目中遇到的真正问题,困扰我的行为不清楚
  • 您的 listBig 是列表列表吗?这是故意的吗?如果是这样,您可能只想调用 append 一次,而不是循环调用。

标签: c++ list qt append qlist


【解决方案1】:

这是 Qt 容器在与类似 stl 的迭代器一起使用时的一个已知限制。 documentation 解释了它。

隐式共享对 STL 风格的迭代器有另一个后果:当迭代器在容器上处于活动状态时,您应该避免复制容器。迭代器指向一个内部结构,如果你复制一个容器,你应该非常小心你的迭代器。

恐怕你将不得不找到一种不同的方式来做你想做的事情(比如使用标准列表或以不同的方式迭代)。

【讨论】:

    【解决方案2】:

    TLDR:在不更改值时使用 cbegin()cend()

    详情:

    • 编译器调用非常量 begin()end() 版本,就像你 问;如果您调用 cbegin()begin(),它可以使用 const 版本 通过 const ref/pointer。
    • QList 尝试写入时复制并在您这样做时共享内存 listBig.append(listSmall);
    • 在非常量 end() 内的下一次迭代中,调用 detach() 确认本地数据后复制数据 多次引用(例如,它被 listBig 内容引用 已经)。

    总而言之,这很好地说明了为什么写时复制难以正确实现。

    BugReport with answer

    【讨论】:

      猜你喜欢
      • 2013-07-04
      • 1970-01-01
      • 2014-10-05
      • 2019-04-23
      • 1970-01-01
      • 2021-12-22
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多