QMap通过指针或值插入QVector <qstring>?

时间:2016-02-01 16:56:34

标签: c++ qt c++11 qmap qvector

我想建立一个设备地图,使地图包含:

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的指针,看起来很麻烦我必须通过QMap删除最后的所有QVector ...

我正在使用c ++ 11,所以也许某种移动语义可以在这里工作?

修改 我修改了代码中的注释,以显示向量不为空。 另外,我会声明一旦存储数据,我就不需要更改数据。

2 个答案:

答案 0 :(得分:4)

没有理由考虑手动分配矢量更好。

当然,你只需要复制一个指针,而不是一个向量,但是复制的空向量仍然很快。存储对象而不是指针的最大好处是你不需要进行手动内存管理。

  

我正在使用c ++ 11,所以也许某种移动语义可以在这里工作?

如果QMap::insert支持移动语义,并且QVector是可移动构造的,就像它们的标准库对应物一样,那么你确实可以将向量移动到地图中。但移动空矢量与复制一样快。

如果QMap有类似emplace函数的std::map,那么您甚至可以在没有移动的情况下就地构建向量。

我不熟悉Qt,但您需要从文档中验证这些详细信息。 Qt是否支持移动语义并不能改变手动内存管理是一种痛苦的事实。

修改:根据documentation QVector似乎是可移动的,但QMap不支持移动语义。但是,正如Arpegius和文档指出的那样,QVector进行了写时复制优化,因此只要未复制复制的向量,就不会复制数据。复制空载体时,这一切都不重要。

再次编辑

如果添加的向量充满了数据,那么复制确实非常昂贵,除非它保持不变。移动可以解决这个问题,但QMap似乎不支持这一点。但是还有另一个技巧:插入一个空向量,然后swap完整的向量与地图中的空向量。

答案 1 :(得分: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上同样运行良好:)

这样您就可以处理已经在地图中的矢量。矢量本身永远不会被复制。向量的成员被复制,但它们是隐式共享的,因此复制实际上是指针复制和原子引用计数增量。

相关问题