Entsprechend dieses Gespräch Bei der Verwendung von C++11 Range Base gibt es einen gewissen Fallstrick for
auf Qt-Containern. Prüfen:
QList<MyStruct> list;
for(const MyStruct &item : list)
{
//...
}
Der Fallstrick, so der Vortrag, liegt im impliziten Teilen. Unter der Haube der Ferngesteuerte for
holt den Iterator aus dem Container. Aber da ist der Container nicht const
der Iterator wird nicht-const
und das reicht anscheinend aus, damit sich der Behälter löst.
Wenn Sie die Lebensdauer eines Containers kontrollieren, ist dies einfach zu beheben, man übergibt das einfach const
Verweis auf den Container, um dessen Verwendung zu erzwingen const_iterator
und nicht zu lösen.
QList<MyStruct> list;
const Qlist<MyStruct> &constList = list;
for(const MyStruct &item : constList)
{
//...
}
Aber was ist mit for
Beispiel Container als Rückgabewerte.
QList<MyStruct> foo() { //... }
void main()
{
for(const MyStruct &item : foo())
{
}
}
Was passiert hier? Wird der Container noch kopiert? Intuitiv würde ich sagen, es ist so, um zu vermeiden, dass dies möglicherweise getan werden muss?
QList<MyStruct> foo() { //... }
main()
{
for(const MyStruct &item : const_cast<const QList<MyStruct>>(foo()))
{
}
}
Ich bin nicht sicher. Ich weiß, es ist ein bisschen ausführlicher, aber ich brauche das, weil ich auf großen Containern häufig bereichsbasierte for-Schleifen verwende, also hat das Gespräch bei mir irgendwie die richtige Saite getroffen.
Bisher verwende ich eine Hilfsfunktion, um den Container in die zu konvertieren const
Referenz, aber wenn es einen kürzeren/einfacheren Weg gibt, dasselbe zu erreichen, würde ich es gerne hören.
Hör auf, dir darüber Sorgen zu machen. Alle Qt-Container implementieren das COW-Muster. Und in den neuesten Versionen implementiert das Qt-Team die Unterstützung von C++11, einschließlich Move-Ctors.
– Dmitri Sasonow
5. März 2016 um 8:01 Uhr
Übrigens, versuche es
const MyStruct& const item : foo()
im const-Stil iterieren.– Dmitri Sasonow
5. März 2016 um 8:02 Uhr
@SaZ Ich werde deinen Vorschlag ausprobieren. Aber in Bezug auf COW sagte der Qt-Entwickler im verlinkten Vortrag ausdrücklich, dass das Erstellen eines nicht konstanten Iterators aus einem Container bedeutet, dass er sich löst. Es ist sinnvoll, weil sie sonst nicht erkennen könnten, ob Sie diesen Iterator tatsächlich verwendet haben, um ihn zu ändern, einfach die Tatsache, dass Sie es können, reicht aus.
– Auferstehung
5. März 2016 um 8:49 Uhr
Ich hatte buchstäblich nie ein Problem damit, einfach zu tun
for(const auto& bla : blas)
Ich sehe nicht, dass es sogar ein Problem damit geben könnte– Wütende Ente
18. März 2016 um 12:00 Uhr
Sollte es nicht sein
const QList<MyStruct> &constList = list;
anstattQlist<MyStruct> &constList = list;
um konstante Iteratoren zu erhalten und das Ablösen zu verhindern? Wenn nein, warum nicht?– vb
4. November 2016 um 8:43 Uhr