2017-10-19 349 views
0

我对Qt Qlist容器有一个有趣的问题。 尝试将QList追加到QList使我的迭代器指向内存的未知部分。将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();总是如果我将小列表添加到大。 这是为什么发生?

P.S. STL列表工作得很好。

+0

我没有关于Qt的想法,但检查此链接,看看u能找到有用https://stackoverflow.com/questions/41438428/qlist-iteration-using-conditions –

+0

@不幸的是,Tharushi Geethma提出的问题只是建议使用stl algorthms,但并不是说追加到QList有什么问题。 – Ivan

+0

你只需要做'listBig.append(listSmall);'如果你想追加它,一次!? – xander

回答

3

这是Qt容器与stl-like迭代器一起使用时的已知限制。 documentation解释它。

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

恐怕你将不得不寻找不同的方法来做你正在做的事情(比如使用标准列表或者迭代方式不同)。

0

TLDR:当您不更改数值时,使用cbegin()cend()

详情:

  • 编译器调用非const begin()end()版本,就像你问 ;如果通过const ref/pointer调用cbegin()begin() ,它可以使用const版本。
  • QList尝试进行写入时拷贝,并在您执行操作时共享内存 listBig.append(listSmall);
  • 在非const内下一个迭代end()有确认的本地数据 不止一次引用(比如,它是由listBig内容 已经提及)后调用 detach()其复制数据。

总而言之,这是写时复制难以正确实施的一个很好的例子。

BugReport with answer