Iterating over a QMap with for

前端 未结 9 1691
执笔经年
执笔经年 2021-01-31 07:02

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

QMap extensions;
//.. 

for(auto e : extensions)
{
  fou         


        
相关标签:
9条回答
  • 2021-01-31 07:56

    If you want the STL style with first and second, do this:

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

    If you want to use what Qt offers, do this:

    for(auto e : extensions.keys())
    {
      fout << e << "," << extensions.value(e) << '\n';
    }
    
    0 讨论(0)
  • 2021-01-31 07:57

    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

    0 讨论(0)
  • 2021-01-31 08:06

    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.

    Considering that the pair uses references, removing the const qualifier for map might allow you to modify values in the map by assigning to e.second. I haven't tested this though.

    I'm using a reference for map as this avoids calling the copy constructor and hopefully allows the compiler to optimize the QMapWrapper class away.


    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';
    }
    
    0 讨论(0)
提交回复
热议问题