1

マップに以下が含まれるようなデバイスのマップを作成したいと考えています。

QString 'DeviceID' と QVector 'Command List'

現在、私は次のようにQMapを持っています:

QMap<QString, QVector<QString> *> devices;

QVector<QString> *pCommands= new QVector<QString>;
//       :
// Fill pCommands with lots of data here
//       :
devices.insert(RadioID, pCommands);

しかし、これが実際にそれよりも優れているかどうか疑問に思っています:

QMap<QString, QVector<QString>> devices;

QVector<QString> commands;
//       :
// Fill commands with lots of data here
//       :
devices.insert(RadioID, commands);

データをコピーするときにQtが非常に効率的なことをどこかで読んだことは確かです。Qt でポインターを使用している人は多くありません。最後にすべての QVector を削除する QMap を通過する必要があるのは面倒です...

私はc++ 11を使用しているので、何らかの移動セマンティックがここで機能する可能性がありますか?

編集 コード内のコメントを変更して、ベクトルが空でないことを示しました。また、データが保存されたら、データを変更する必要はないと述べます。

4

2 に答える 2

4

より良いベクトルを手動で割り当てることを検討する理由はありません。

確かに、ベクターではなくポインターをコピーするだけで済みますが、空のベクターのコピーは依然として非常に高速です。ポインターではなくオブジェクトを格納する最大のメリットは、手動でメモリを管理する必要がないことです。

私はc++ 11を使用しているので、何らかの移動セマンティックがここで機能する可能性がありますか?

QMap::insert移動セマンティクスをサポートし、対応する標準ライブラリのように移動構築可能である場合QVector、ベクトルを実際にマップに移動できます。しかし、空ベクトルの移動は、コピーと同じくらい高速です。

のような関数がある場合QMapは、移動することなく、その場でベクトルを構築することさえできます。emplacestd::map

私は Qt に詳しくないので、ドキュメントから詳細を確認する必要があります。Qt がムーブ セマンティクスをサポートしているかどうかにかかわらず、手動のメモリ管理が苦痛であるという事実は変わりません。


編集:ドキュメント QVectorによると、移動可能であるように見えますが、QMap移動セマンティクスはサポートされていません。ただし、Arpegius とドキュメントが指摘しているように、QVectorコピー オン ライトの最適化を行うため、コピーされたベクトルが変更されない限り、データはコピーされません。空のベクターをコピーする場合、これは実際には問題になりません。


再編集

追加されたベクトルがデータでいっぱいの場合、変更されない限り、コピーは非常に高価です。移動はそれを改善しQMapますが、それをサポートしていないようです. ただし、別のトリックがあります。空のベクターを挿入してから、空のベクターをswap含む完全なベクターをマップに挿入します。

于 2016-02-01T17:13:03.177 に答える
1

それを行うための最も単純でかなり慣用的な方法は次のとおりです。

QMap<QString, QVector<QString>> devices;

// Get the vector constructed in the map itself.
auto & commands = devices[RadioID];
// Fill commands with lots of data here - a bit faster
commands.resize(2);
commands[0] = "Foo";
commands[1] = "Bar";
// Fill commands with lots of data here - a bit slower
commands.append("Baz");
commands.append("Fan");

このパターンは Qt やその他のコードでよく見られますが、C++98 と C++11 で同じように機能する最も簡単な方法です :)

このようにして、マップに既に存在するベクトルに取り組んでいます。ベクトル自体は決してコピーされません。ベクターのメンバーはコピーされますが、それらは暗黙的に共有されるため、コピーは文字通りポインターのコピーであり、アトミックな参照カウントのインクリメントです。

于 2016-02-02T14:18:32.753 に答える