this talkによると、QtコンテナでC++ 11の範囲ベースfor
を使用すると、一定の落とし穴があります。考えてみましょう:QtでC++ 11レンジベースのforループを正しく使用する
QList<MyStruct> list;
for(const MyStruct &item : list)
{
//...
}
落ち込みは、暗黙の共有に由来します。フードの下では、レンジベースのforはコンテナからイテレータを取得します。しかし、コンテナはconstではないので、インターレーターは非constであり、それは明らかにコンテナが分離するのに十分である。
これは簡単に修正できますが、const参照をコンテナに渡して強制的にconst_iteratorを使用し、デタッチしないようにします。
QList<MyStruct> list;
const Qlist<MyStruct> &constList = list;
for(const MyStruct &item : constList)
{
//...
}
ただし、たとえばコンテナは戻り値としてどうなりますか。
QList<MyStruct> foo() { //... }
void main()
{
for(const MyStruct &item : foo())
{
}
}
ここではどうなりますか?コンテナはまだコピーされていますか?直感的に言えば、これを行う必要があるかもしれないことを避けることだと思いますか?
QList<MyStruct> foo() { //... }
main()
{
for(const MyStruct &item : const_cast<const QList<MyStruct>>(foo()))
{
}
}
わかりません。私はそれがもう少し冗長であることを知っていますが、私はこれを必要とします。
これまでコンテナをconst参照に変換するためにヘルパー関数を使用していましたが、同じ目的を達成するためのより簡単な方法があれば、聞いてみたいと思います。
それを心配するのをやめてください。すべてのQtコンテナはCOWパターンを実装します。最新のバージョンでは、QtチームはC++ 11のサポートを実装しています。 –
Btw、 'const MyStruct&const item:foo()'を使ってconstスタイルで反復処理してみてください。 –
@SaZ私はあなたの提案をお試しになります。しかし、COWに関して、リンクされた会話のQt開発者は、コンテナから非constイテレータを作成すると、それが分離することを明示的に述べました。そうでなければ、イテレータを実際に使用してそれを変更したかどうかを検出することができなかったので、理にかなっています。 – Resurrection