1

我有一个理解问题,为什么以下代码不会将任何 QString-Objects 存储到我的 QList 中

QMap<QString, QList<QString> >map;
map = QMap<QString, QList<QString> >();
map.insert("eins", QList<QString>());
QList<QString> listInMap = map["eins"];
listInMap.append("test1");
listInMap.append("test2");
QList<QString> copyOfListInMap = map.value("eins");
qDebug() << copyOfListInMap.count();

输出:0

4

2 回答 2

2

原因很简单:写时复制,又名。隐式共享

QList<QString> listInMap = map["eins"];

此时,您还没有得到硬拷贝,只有“参考”。这在标准 C++ 意义上是不公平的,但可以将其想象为“浅拷贝”。但是,当您开始在此处追加时,列表将被复制,而原始列表将留空。这是因为 QList 是以CoW (copy-on-write) 的方式实现的

listInMap.append("test1");
listInMap.append("test2");

在旁注中,您可能希望查看QStringList。虽然它继承了 QList,但它也有一些额外的便利方法。

现在,您可能会问:How am I supposed to fill my map in, then?.

多图

我个人建议使用QMultiMap或至少QMap使用insertMulti

主文件

#include <QMap>
#include <QDebug>
#include <QString>

int main()
{
    QMultiMap<QString, QString> map;
    map.insert("eins", "test1");
    map.insert("eins", "test2");
    qDebug() << map.count();
    return 0;
}

主程序

TEMPLATE = app
TARGET = main
QT = core
SOURCES += main.cpp

构建并运行

qmake && make && ./main

输出

2

单张地图

如果您坚持当前的方法,我建议要么将该值附加到一个新的 QStringList 中,您将使用它覆盖该值,或者保留对完全相同列表的引用。

话虽如此,在您的情况下,甚至考虑使用外部存储进行插入看起来有点矫枉过正。以我的拙见,您应该立即这样做。

主文件

#include <QMap>
#include <QDebug>
#include <QString>

int main()
{
    QMap<QString, QStringList> map;
    map.insert("eins", QStringList{"test1", "test2"});
    qDebug() << map.value("eins").count();
    return 0;
}

主程序

TEMPLATE = app
TARGET = main
QT = core
CONFIG += c++11
SOURCES += main.cpp

构建并运行

qmake && make && ./main

输出

2
于 2014-12-23T16:20:30.290 回答
1

根据文档,您的示例应更改如下:

QMap<QString, QList<QString> >map;
QList<QString> & listInMap = map["eins"]; // use reference here
listInMap.append("test1");
listInMap.append("test2");
QList<QString> copyOfListInMap = map.value("eins");
qDebug() << copyOfListInMap.count();
于 2014-12-23T16:47:33.893 回答