C++11 std::initializer_list for container



  • Dear peoples,

    I hope C++ gurus will appreciate this post. I recently have gcc 5.1.0 with mingw-w64 and I build Qt 5.3.2 on it.

    Now I'm playing a bit with the C++11 and C++14 features. One of them is the std::initializer_list.

    #include <cstddef>
    #include <cstdio>
    #include <cstdint>
    #include <QHash>
    #include <QString>
    #include <QList>
    
    int main()
    {
      // my favorite US states
      typedef QHash< QString, int8_t > StateRank;
      static const StateRank hash{
        { "Arizona", 6 },
        { "Montana", 2 },
        { "Nevada", 5 },
        { "Texas", 1 },
        { "North Carolina", 3 },
        { "New Mexico", 4 }};
    
      printf( "hash contents:\n" );
      QList< StateRank::key_type > key_list = hash.keys();
      QList< StateRank::mapped_type > value_list = hash.values();
    
      for ( int i = 0; i < key_list.size(); ++i )
      {
        printf( "%s, %d\n",
          key_list.at( i ).toLocal8Bit().data(),
          value_list.at( i ) );
      }
    
      getchar();
      return 0;
    }
    

    My objective is to have a lookup table that is valid for the full existence of the executable process (the program). I also declared it const because it should never change. The program does what I expect it does.

    I would like to question how this QHash container is constructed. I hope this is the way for minimal CPU intervention. What I assume it does in general terms (correct me where I am wrong). When I launch the application:

    1. Windows calls CreateProcess on the executable.
    2. The program gets copied (loaded) into working memory.
    3. And as part of this copy process it creates the container object hash. Without CPU assistance.

    I might be a bit off in this. But I think you'll get the idea about the kind of knowledge I'm aiming for. I couldn't find good search terms to obtain info on the internet about this.

    Does this program example provide maximum performance? Can I somehow have QStringRef as the key type, or wouldn't that be a good idea anyway? Obviously forget about the printing part of it. In the non-example application I will just need the functions hash.contains( key ) and hash.value( key ).

    Thanks for your time, I appreciate it!!

    Best regards,
    Maarten Verhage



  • @Maarten-Verhage said in C++11 std::initializer_list for container:

    QStringRef

    Sounds risky to use as your key.

    Warning: A QStringRef is only valid as long as the referenced string exists. If the original string is deleted, the string reference points to an invalid memory location.

    Would you find a map better for this application? Map sorts your key and everything... I use the std:: containers mostly because range loops are so nice and concise.

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
        qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
    
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        const std::map<std::string, int> StateIndexMap {
            { "Arizona"         , 6 },
            { "Montana"         , 2 },
            { "Nevada"          , 5 },
            { "Texas"           , 1 },
            { "North Carolina"  , 3 },
            { "New Mexico"      , 4 },
          };
         const QMap<QString, int> StateIndexQMap {
             { "Arizona"         , 6 },
             { "Montana"         , 2 },
             { "Nevada"          , 5 },
             { "Texas"           , 1 },
             { "North Carolina"  , 3 },
             { "New Mexico"      , 4 },
           };
         const std::map<int, std::string> IndexStateMap {
             { 6, "Arizona"       },
             { 2, "Montana"       },
             { 5, "Nevada"        },
             { 1, "Texas"         },
             { 3, "North Carolina"},
             { 4, "New Mexico"    },
           };
    
    qDebug()<<"std::map<std::string, int> StateIndexMap";
    
        for(const auto& StateIter : StateIndexMap){
            qDebug()<<"StateIter.first: "<<StateIter.first.c_str()<<", StateIter.second: "<<StateIter.second;
            printf("%s, %d", StateIter.first.c_str(), StateIter.second );
        }
    
    qDebug()<<"\r\nQMap<QString, int> StateIndexQMap";
    
        QMap<QString, int>::const_iterator iterState = StateIndexQMap.constBegin();
        while (iterState != StateIndexQMap.constEnd()) {
            qDebug()<<" key(): "<<iterState.key().toLatin1().data()<<", value(): "<< iterState.value();
            printf("%s, %d", iterState.key().toLatin1().data(), iterState.value() );
            ++iterState;
        }
    
    qDebug()<<"\r\nstd::map<int, std::string> IndexStateMap";
    
        for(const auto& Iter : IndexStateMap){
            qDebug()<<"Iter.first: "<<Iter.first<<", Iter.second: "<<Iter.second.c_str();
            printf("%d, %s", Iter.first, Iter.second.c_str() );
        }
    
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
        return app.exec();
    }
    
    Console output:
    std::map<std::string, int> StateIndexMap
    StateIter.first:  Arizona , StateIter.second:  6
    StateIter.first:  Montana , StateIter.second:  2
    StateIter.first:  Nevada , StateIter.second:  5
    StateIter.first:  New Mexico , StateIter.second:  4
    StateIter.first:  North Carolina , StateIter.second:  3
    StateIter.first:  Texas , StateIter.second:  1
    
    QMap<QString, int> StateIndexQMap
     key():  Arizona , value():  6
     key():  Montana , value():  2
     key():  Nevada , value():  5
     key():  New Mexico , value():  4
     key():  North Carolina , value():  3
     key():  Texas , value():  1
    
    std::map<int, std::string> IndexStateMap
    Iter.first:  1 , Iter.second:  Texas
    Iter.first:  2 , Iter.second:  Montana
    Iter.first:  3 , Iter.second:  North Carolina
    Iter.first:  4 , Iter.second:  New Mexico
    Iter.first:  5 , Iter.second:  Nevada
    Iter.first:  6 , Iter.second:  Arizona
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.