使用 for 迭代 QMap

发布于 2024-12-21 11:38:41 字数 328 浏览 6 评论 0原文

我有一个 QMap 对象,我正在尝试将其内容写入文件。

QMap<QString, QString> extensions;
//.. 

for(auto e : extensions)
{
  fout << e.first << "," << e.second << '\n';
}  

为什么我会得到:错误:“class QString”没有名为“first”或“second”的成员

e不是QPair类型吗?

I've a QMap object and I am trying to write its content to a file.

QMap<QString, QString> extensions;
//.. 

for(auto e : extensions)
{
  fout << e.first << "," << e.second << '\n';
}  

Why do I get: error: 'class QString' has no member named 'first' nor 'second'

Is e not of type QPair?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

小矜持 2024-12-28 11:38:42

Qt 6.4 及更高版本

使用 QMap::asKeyValueRange 如下:

for (auto [key, value] : map.asKeyValueRange()) {
    qDebug() << key << value;
}

从 Qt 5.10 开始到 Qt 6.3

使用 QMap::keyValueBeginQMap::keyValueEnd 如下:

for (auto it = map.keyValueBegin(); it != map.keyValueEnd(); ++it) {
    qDebug() << it->first << it->second;
}

QMap::asKeyValueRange 函数可以使用 只需几行代码,也允许在 Qt 5.10 到 Qt 6.3 中使用键值范围(需要 C++17 ):

for (auto [key, value] : asKeyValueRange(map)) {
    qDebug() << key << value;
}

从 Qt 4 到 Qt 5.9

使用 QMap::beginQMap::end 如下:

for (auto it = map.begin(); it != map.end(); ++it) {
    qDebug() << it.key() << it.value();
}

可以使用 一些附加代码行将循环包装到范围中,从而允许使用范围-基于Qt 4 到 Qt 5.9 中的 for 循环(需要 C++11):

for (auto it : toRange(map)) {
    qDebug() << it.key() << it.value();
}

其他选项

(这是原始答案。)

使用 QMap::toStdMap 将地图转换为 std::map,然后对其进行迭代。请注意,性能将较差,因为这将复制整个地图。

for (auto it : map.toStdMap()) {
    qDebug() << it.first << it.second;
}

迭代 QMap::keys 并查找每个关联的 QMap::value。请注意,性能将极差,因为这将复制所有键,然后单独搜索每个值。

for (auto key : map.keys()) {
    qDebug() << key << map.value(key);
}

Qt 6.4 and later

Use QMap::asKeyValueRange as follows:

for (auto [key, value] : map.asKeyValueRange()) {
    qDebug() << key << value;
}

From Qt 5.10 to Qt 6.3

Use QMap::keyValueBegin and QMap::keyValueEnd as follows:

for (auto it = map.keyValueBegin(); it != map.keyValueEnd(); ++it) {
    qDebug() << it->first << it->second;
}

The QMap::asKeyValueRange function can be backported from Qt 6.4 with just a few lines of code, allowing to use key-value ranges in Qt 5.10 to Qt 6.3 as well (C++17 required):

for (auto [key, value] : asKeyValueRange(map)) {
    qDebug() << key << value;
}

From Qt 4 to Qt 5.9

Use QMap::begin and QMap::end as follows:

for (auto it = map.begin(); it != map.end(); ++it) {
    qDebug() << it.key() << it.value();
}

The loop can be wrapped into a range with some lines of additional code, allowing to use range-based for loops in Qt 4 to Qt 5.9 as well (C++11 required):

for (auto it : toRange(map)) {
    qDebug() << it.key() << it.value();
}

Other options

(This is the original answer.)

Use QMap::toStdMap to convert the map into a std::map and then iterate over that. Note that the performance will be poor, since this will copy the entire map.

for (auto it : map.toStdMap()) {
    qDebug() << it.first << it.second;
}

Iterate over the QMap::keys and look up each associated QMap::value. Note that the performance will be extremely poor, since this will copy all keys and then separately search for each value.

for (auto key : map.keys()) {
    qDebug() << key << map.value(key);
}
玩心态 2024-12-28 11:38:42

C++11 基于范围的 for 使用取消引用的迭代器的类型作为自动推导的“游标”类型。这里,它是表达式*map.begin()的类型。

由于 QMap::iterator::operator*() 返回对值(QString & 类型)的引用,因此无法使用该键访问那个方法。

您应该使用文档中描述的迭代器方法之一,但应避免使用

  • keys() 因为它涉及创建键列表,然后搜索每个键的值,或者,
  • toStdMap () 因为它将所有地图元素复制到另一个地图元素,

这并不是最佳选择。


You could also use a wrapper to get QMap::iterator as the auto type:

template<class Map>
struct RangeWrapper {
    typedef typename Map::iterator MapIterator;
    Map ↦

    RangeWrapper(Map & map_) : map(map_) {}

    struct iterator {
        MapIterator mapIterator;
        iterator(const MapIterator &mapIterator_): mapIterator(mapIterator_) {}
        MapIterator operator*() {
            return mapIterator;
        }
        iterator & operator++() {
            ++mapIterator;
            return *this;
        }
        bool operator!=(const iterator & other) {
            return this->mapIterator != other.mapIterator;
        }
    };
    iterator begin() {
        return map.begin();
    }
    iterator end() {
        return map.end();
    }
};

// Function to be able to use automatic template type deduction
template<class Map>
RangeWrapper<Map> toRange(Map & map)
{
    return RangeWrapper<Map>(map);
}

// Usage code
QMap<QString, QString> extensions;
...
for(auto e : toRange(extensions)) {
    fout << e.key() << "," << e.value() << '\n';
}

这里还有另一个包装器。

C++11 range-based-for uses the type of the dereferenced iterator as the automatically deduced "cursor" type. Here, it is the type of the expression *map.begin().

And since QMap::iterator::operator*() returns a reference to the value (of type QString &), the key isn't accessible using that method.

You should use one of the iterator methods described in the documentation but you should avoid using

  • keys() because it involves creating a list of keys and then searching the value for each key, or,
  • toStdMap() because it copies all the map elements to another one,

and that wouldn't be very optimal.


You could also use a wrapper to get QMap::iterator as the auto type:

template<class Map>
struct RangeWrapper {
    typedef typename Map::iterator MapIterator;
    Map ↦

    RangeWrapper(Map & map_) : map(map_) {}

    struct iterator {
        MapIterator mapIterator;
        iterator(const MapIterator &mapIterator_): mapIterator(mapIterator_) {}
        MapIterator operator*() {
            return mapIterator;
        }
        iterator & operator++() {
            ++mapIterator;
            return *this;
        }
        bool operator!=(const iterator & other) {
            return this->mapIterator != other.mapIterator;
        }
    };
    iterator begin() {
        return map.begin();
    }
    iterator end() {
        return map.end();
    }
};

// Function to be able to use automatic template type deduction
template<class Map>
RangeWrapper<Map> toRange(Map & map)
{
    return RangeWrapper<Map>(map);
}

// Usage code
QMap<QString, QString> extensions;
...
for(auto e : toRange(extensions)) {
    fout << e.key() << "," << e.value() << '\n';
}

There is another wrapper here.

↙厌世 2024-12-28 11:38:42

对于对优化感兴趣的人,我尝试了几种方法,做了一些微观基准测试,我可以得出结论:STL 风格方法明显更快

我尝试使用以下方法添加整数:

  • QMap::values()
  • Java 样式迭代器(如文档中所建议)
  • STL 样式迭代器(也如文档中所建议)

的整数求和进行了比较

我将其与 QList/QVector结果 :

Reference vector :   244  ms
Reference list :     1239  ms

QMap::values() :     6504  ms
Java style iterator :    6199  ms
STL style iterator :     2343  ms

感兴趣的人的代码:

#include <QDateTime>
#include <QMap>
#include <QVector>
#include <QList>
#include <QDebug>

void testQMap(){
    QMap<int, int> map;
    QVector<int> vec;
    QList<int> list;

    int nbIterations = 100;
    int size = 1000000;
    volatile int sum = 0;

    for(int i = 0; i<size; ++i){
        int randomInt = qrand()%128;
        map[i] = randomInt;
        vec.append(randomInt);
        list.append(randomInt);
    }


    // Rererence vector/list
    qint64 start = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        for(int j : vec){
            sum += j;
        }
    }
    qint64 end = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "Reference vector : \t" << (end-start) << " ms";

    qint64 startList = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        for(int j : list){
            sum += j;
        }
    }
    qint64 endList = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "Reference list : \t" << (endList-startList) << " ms";

    // QMap::values()
    qint64 start0 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        QList<int> values = map.values();
        for(int k : values){
            sum += k;
        }
    }
    qint64 end0 = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "QMap::values() : \t" << (end0-start0) << " ms";


    // Java style iterator
    qint64 start1 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        QMapIterator<int, int> it(map);
        while (it.hasNext()) {
            it.next();
            sum += it.value();
        }
    }
    qint64 end1 = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "Java style iterator : \t" << (end1-start1) << " ms";


    // STL style iterator
    qint64 start2 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        QMap<int, int>::const_iterator it = map.constBegin();
        auto end = map.constEnd();
        while (it != end) {
            sum += it.value();
            ++it;
        }
    }
    qint64 end2 = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "STL style iterator : \t" << (end2-start2) << " ms";


    qint64 start3 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        auto end = map.cend();
        for (auto it = map.cbegin(); it != end; ++it)
        {
            sum += it.value();
        }
    }
    qint64 end3 = QDateTime::currentMSecsSinceEpoch();

    qDebug() << "STL style iterator v2 : \t" << (end3-start3) << " ms";
}

2017 年 7 月编辑:我在我的新笔记本电脑(Qt 5.9,i7-7560U)上再次运行此代码,并得到了一些有趣的变化

Reference vector :   155  ms 
Reference list :     157  ms
QMap::values():      1874  ms 
Java style iterator: 1156  ms 
STL style iterator:  1143  ms

STL 风格和 Java 风格有该基准测试中的表现非常相似

For people interested in optimizations, I have tried several approaches, did some micro benchmarks, and I can conclude that STL style approach is significantly faster.

I have tried adding integers with these methods :

  • QMap::values()
  • Java style iterator (as advised in the documentation)
  • STL style iterator (as advised in the documentation too)

And I have compared it with summing integers of a QList/QVector

Results :

Reference vector :   244  ms
Reference list :     1239  ms

QMap::values() :     6504  ms
Java style iterator :    6199  ms
STL style iterator :     2343  ms

Code for those interested :

#include <QDateTime>
#include <QMap>
#include <QVector>
#include <QList>
#include <QDebug>

void testQMap(){
    QMap<int, int> map;
    QVector<int> vec;
    QList<int> list;

    int nbIterations = 100;
    int size = 1000000;
    volatile int sum = 0;

    for(int i = 0; i<size; ++i){
        int randomInt = qrand()%128;
        map[i] = randomInt;
        vec.append(randomInt);
        list.append(randomInt);
    }


    // Rererence vector/list
    qint64 start = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        for(int j : vec){
            sum += j;
        }
    }
    qint64 end = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "Reference vector : \t" << (end-start) << " ms";

    qint64 startList = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        for(int j : list){
            sum += j;
        }
    }
    qint64 endList = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "Reference list : \t" << (endList-startList) << " ms";

    // QMap::values()
    qint64 start0 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        QList<int> values = map.values();
        for(int k : values){
            sum += k;
        }
    }
    qint64 end0 = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "QMap::values() : \t" << (end0-start0) << " ms";


    // Java style iterator
    qint64 start1 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        QMapIterator<int, int> it(map);
        while (it.hasNext()) {
            it.next();
            sum += it.value();
        }
    }
    qint64 end1 = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "Java style iterator : \t" << (end1-start1) << " ms";


    // STL style iterator
    qint64 start2 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        QMap<int, int>::const_iterator it = map.constBegin();
        auto end = map.constEnd();
        while (it != end) {
            sum += it.value();
            ++it;
        }
    }
    qint64 end2 = QDateTime::currentMSecsSinceEpoch();
    qDebug() << "STL style iterator : \t" << (end2-start2) << " ms";


    qint64 start3 = QDateTime::currentMSecsSinceEpoch();
    for(int i = 0; i<nbIterations; ++i){
        sum = 0;
        auto end = map.cend();
        for (auto it = map.cbegin(); it != end; ++it)
        {
            sum += it.value();
        }
    }
    qint64 end3 = QDateTime::currentMSecsSinceEpoch();

    qDebug() << "STL style iterator v2 : \t" << (end3-start3) << " ms";
}

Edit July 2017 : I ran this code again on my new laptop (Qt 5.9, i7-7560U) and got some interesting changes

Reference vector :   155  ms 
Reference list :     157  ms
QMap::values():      1874  ms 
Java style iterator: 1156  ms 
STL style iterator:  1143  ms

STL style and Java style have very similar performances in this benchmark

人生百味 2024-12-28 11:38:42

QMap::iterator 使用 key() 和 value() - 可以在 Qt 4.8 的文档文档Qt-5

编辑:

基于范围的 for 循环生成与此类似的代码(请参阅 CPP 参考):

{
    for (auto __begin = extensions.begin(), __end = extensions.end();
            __begin != __end; ++__begin) {
        auto e = *__begin; // <--- this is QMap::iterator::operator*()
        fout << e.first << "," << e.second << '\n';
    }
} 

QMap::iterator::iterator*() 等价于 QMap::iterator::value(),并且不给出对。

编写此代码的最佳方法是不使用基于范围的 for 循环:

auto end = extensions.cend();
for (auto it = extensions.cbegin(); it != end; ++it)
{
    std::cout << qPrintable(it.key()) << "," << qPrintable(it.value());
}

QMap::iterator uses key() and value() - which can be found easily in the documentation for Qt 4.8 or the documentation for Qt-5.

Edit:

A range-based for loop generates codes similar to this (see CPP reference):

{
    for (auto __begin = extensions.begin(), __end = extensions.end();
            __begin != __end; ++__begin) {
        auto e = *__begin; // <--- this is QMap::iterator::operator*()
        fout << e.first << "," << e.second << '\n';
    }
} 

QMap::iterator::iterator*() is equivalent to QMap::iterator::value(), and does not give a pair.

The best way to write this is without range-based for loop:

auto end = extensions.cend();
for (auto it = extensions.cbegin(); it != end; ++it)
{
    std::cout << qPrintable(it.key()) << "," << qPrintable(it.value());
}
岁吢 2024-12-28 11:38:42

在“旧”C++ 中,使用 Qt,您可以这样做:

QMap< QString, whatever > extensions;
//...
foreach( QString key, extensions.keys() )
{
    fout << key << "," << extensions.value( key ) << '\n';
}

我这里没有 C++11 编译器,但也许以下内容会起作用:

for( auto key: extensions.keys() )
{
    fout << key << "," << extensions.value( key ) << '\n';
}

您也可以使用迭代器,如果您更喜欢使用,请查看 hmuelners 链接他们

In "old" C++, using Qt, you would do it like this:

QMap< QString, whatever > extensions;
//...
foreach( QString key, extensions.keys() )
{
    fout << key << "," << extensions.value( key ) << '\n';
}

I don't have a C++11 compiler here but maybe the following will work:

for( auto key: extensions.keys() )
{
    fout << key << "," << extensions.value( key ) << '\n';
}

You can also use iterators instead, check out hmuelners link if you prefer using them

柠檬色的秋千 2024-12-28 11:38:42

从 Qt 5.10 开始,您可以使用一个简单的包装类来使用基于范围的 for 循环,但仍然能够访问映射条目的键和值。

将以下代码放在源文件顶部或包含的标头中:

template<class K,class V>
struct QMapWrapper {
    const QMap<K,V> map;
    QMapWrapper(const QMap<K,V>& map) : map(map) {}
    auto begin() { return map.keyValueBegin(); }
    auto end()   { return map.keyValueEnd();   }
};

要迭代所有条目,您只需编写:

QMap<QString, QString> extensions;
//.. 

for(auto e : QMapWrapper(extensions))
{
  fout << e.first << "," << e.second << '\n';
}

e 的类型将为 std::pair< ;const QString&, const QString> 正如 QKeyValueIterator 文档

成员变量 map 是映射的隐式共享副本,以避免与 临时值。因此,只要您不在循环内修改映射,则只会产生很小的恒定开销。


上面的例子使用了类模板参数推导,这是在C++中引入的17.如果您使用的是较旧的标准,则在调用构造函数时必须指定 QMapWrapper 的模板参数。在这种情况下,工厂方法可能很有用:

template<class K,class V>
QMapWrapper<K,V> wrapQMap(const QMap<K,V>& map) {
    return QMapWrapper<K,V>(map);
}
    

它用作:

for(auto e : wrapQMap(extensions))
{
  fout << e.first << "," << e.second << '\n';
}

Since Qt 5.10 you can use a simple wrapper class to use a range based for loop, but still be able to access both the key and value of the map entries.

Put the following code somewhere at the top of your source file or in a header that you include:

template<class K,class V>
struct QMapWrapper {
    const QMap<K,V> map;
    QMapWrapper(const QMap<K,V>& map) : map(map) {}
    auto begin() { return map.keyValueBegin(); }
    auto end()   { return map.keyValueEnd();   }
};

To iterate over all entries you can simply write:

QMap<QString, QString> extensions;
//.. 

for(auto e : QMapWrapper(extensions))
{
  fout << e.first << "," << e.second << '\n';
}

The type of e will be std::pair<const QString&, const QString&> as is partially specified in the QKeyValueIterator documentation.

The member variable map is an implicitly shared copy of the map, to avoid a segmentation fault in case this is used with temporary values. Hence as long as you do not modify the map within the loop, this only has a small constant overhead.


The above example uses class template argument deduction, which was introduced in C++17. If you're using an older standard, the template parameters for QMapWrapper must be specified when calling the constructor. In this case a factory method might be useful:

template<class K,class V>
QMapWrapper<K,V> wrapQMap(const QMap<K,V>& map) {
    return QMapWrapper<K,V>(map);
}
    

This is used as:

for(auto e : wrapQMap(extensions))
{
  fout << e.first << "," << e.second << '\n';
}
稳稳的幸福 2024-12-28 11:38:42

KDAB 的 Ivan Čukić 有一篇博客文章 解释了如何使用 C++17 结构化绑定,无需复制容器:

template <typename T>
class asKeyValueRange
{
public:
    asKeyValueRange(T& data) : m_data{data} {}

    auto begin() { return m_data.keyValueBegin(); }

    auto end() { return m_data.keyValueEnd(); }

private:
    T& m_data;
};

...

QMap<QString, QString> extensions;

for (auto&& [key, value]: asKeyValueRange(extensions))
{
    fout << key << ',' << value << '\n';
} 

Ivan Čukić of KDAB has a blog post that explains how to iterate over a QMap with C++17 structured bindings without copying the container:

template <typename T>
class asKeyValueRange
{
public:
    asKeyValueRange(T& data) : m_data{data} {}

    auto begin() { return m_data.keyValueBegin(); }

    auto end() { return m_data.keyValueEnd(); }

private:
    T& m_data;
};

...

QMap<QString, QString> extensions;

for (auto&& [key, value]: asKeyValueRange(extensions))
{
    fout << key << ',' << value << '\n';
} 
断肠人 2024-12-28 11:38:42

从 Qt 6.4 开始,您可以使用方法 asKeyValueRange() 如下:

for(auto pair : extensions.asKeyValueRange()) {
    pair.first;    // key access
    pair.second;   // value access
}

这甚至适用于花哨的 结构化绑定

for(auto& [key, value] : extensions.asKeyValueRange()) {
    fout << key << "," << value << '\n';
}

Since Qt 6.4 you can use the method asKeyValueRange() as follows:

for(auto pair : extensions.asKeyValueRange()) {
    pair.first;    // key access
    pair.second;   // value access
}

This even works for the fancy structured bindings.

for(auto& [key, value] : extensions.asKeyValueRange()) {
    fout << key << "," << value << '\n';
}
一个人练习一个人 2024-12-28 11:38:42

从 Qt 5.10 开始,您可以包装 QMap::keyValueBeginQMap::keyValueEnd 进入一个范围并然后使用基于范围的 for 循环来迭代该范围。这无需复制地图数据即可工作,并且支持 const 和 rvalue 对象。 需要 C++17 编译器。

template<typename T> class KeyValueRange {
private:
    T iterable; // This is either a reference or a moved-in value. The map data isn't copied.
public:
    KeyValueRange(T &iterable) : iterable(iterable) { }
    KeyValueRange(std::remove_reference_t<T> &&iterable) noexcept : iterable(std::move(iterable)) { }
    auto begin() const { return iterable.keyValueBegin(); }
    auto end() const { return iterable.keyValueEnd(); }
};

template <typename T> auto asKeyValueRange(T &iterable) { return KeyValueRange<T &>(iterable); }
template <typename T> auto asKeyValueRange(const T &iterable) { return KeyValueRange<const T &>(iterable); }
template <typename T> auto asKeyValueRange(T &&iterable) noexcept { return KeyValueRange<T>(std::move(iterable)); }

像这样使用它:

for (auto [key, value] : asKeyValueRange(map)) {
    qDebug() << key << value;
}

注意:如果您只需要在迭代非时读取该值 code>const 映射,那么您应该使用 asKeyValueRange(std::as_const(map)) 代替。这将确保迭代不会触发不需要的 copy-on-write操作

注意:这个确切的代码实际上也适用于QHashQMultiHashQMultiMap

Since Qt 5.10, you can wrap QMap::keyValueBegin and QMap::keyValueEnd into a range and then use a range-based for loop to iterate that range. This works without copying the map data and supports both const and rvalue objects. C++17 compiler needed.

template<typename T> class KeyValueRange {
private:
    T iterable; // This is either a reference or a moved-in value. The map data isn't copied.
public:
    KeyValueRange(T &iterable) : iterable(iterable) { }
    KeyValueRange(std::remove_reference_t<T> &&iterable) noexcept : iterable(std::move(iterable)) { }
    auto begin() const { return iterable.keyValueBegin(); }
    auto end() const { return iterable.keyValueEnd(); }
};

template <typename T> auto asKeyValueRange(T &iterable) { return KeyValueRange<T &>(iterable); }
template <typename T> auto asKeyValueRange(const T &iterable) { return KeyValueRange<const T &>(iterable); }
template <typename T> auto asKeyValueRange(T &&iterable) noexcept { return KeyValueRange<T>(std::move(iterable)); }

Use it like this:

for (auto [key, value] : asKeyValueRange(map)) {
    qDebug() << key << value;
}

Note: If you only need read access to the value while iterating a non-const map, then you should use asKeyValueRange(std::as_const(map)) instead. This will make sure that the iteration doesn't trigger an unneeded copy-on-write operation.

Note: This exact code actually also works for QHash, QMultiHash and QMultiMap as well.

笛声青案梦长安 2024-12-28 11:38:42

另一种方便的方法来自 QMap 文档。它允许显式访问键和值(Java 样式迭代器):

QMap<QString, QString> extensions;
// ... fill extensions
QMapIterator<QString, QString> i(extensions);
while (i.hasNext()) {
    i.next();
    qDebug() << i.key() << ": " << i.value();
}

如果您希望能够覆盖,请改用 QMutableMapIterator。

如果您只想读取值而不需要键(使用 Qt 的 foreach 和 c++),还有另一种方便的 Qt 方法11):

QMap<QString, QString> extensions;
// ... fill extensions
foreach (const auto& value, extensions)
{
    // to stuff with value
}

Another convenient method, from the QMap Docs. It allows explicit access to key and value (Java-Style iterator):

QMap<QString, QString> extensions;
// ... fill extensions
QMapIterator<QString, QString> i(extensions);
while (i.hasNext()) {
    i.next();
    qDebug() << i.key() << ": " << i.value();
}

In case you want to be able to overwrite, use QMutableMapIterator instead.

There's another convenient Qt method, if you're only interested in reading the values, without the keys (using Qts foreach and c++11):

QMap<QString, QString> extensions;
// ... fill extensions
foreach (const auto& value, extensions)
{
    // to stuff with value
}
ゞ记忆︶ㄣ 2024-12-28 11:38:42

我用这样的东西来实现我自己的结果。以防万一有人需要单独的键和值。

{
   QMap<int,string> map; 

   map.insert(1,"One");
   map.insert(2,"Two");
   map.insert(3,"Three");
   map.insert(4,"Four");   

   fout<<"Values in QMap 'map' are:"<<endl;
   foreach(string str,map)
   {
     cout<<str<<endl;
   };


   fout<<"Keys in QMap 'map' are:"<<endl;
   foreach(int key,map.keys())
   {
     cout<<key<<endl;
   }; 
}  

I used something like this, to achieve my own result. Just in case someone needed the keys and values separately.

{
   QMap<int,string> map; 

   map.insert(1,"One");
   map.insert(2,"Two");
   map.insert(3,"Three");
   map.insert(4,"Four");   

   fout<<"Values in QMap 'map' are:"<<endl;
   foreach(string str,map)
   {
     cout<<str<<endl;
   };


   fout<<"Keys in QMap 'map' are:"<<endl;
   foreach(int key,map.keys())
   {
     cout<<key<<endl;
   }; 
}  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文