Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. C++11 std::initializer_list for container

C++11 std::initializer_list for container

Scheduled Pinned Locked Moved Unsolved C++ Gurus
2 Posts 2 Posters 1.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Maarten Verhage
    wrote on 7 Aug 2017, 02:36 last edited by
    #1

    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

    1 Reply Last reply
    0
    • 6 Offline
      6 Offline
      6thC
      wrote on 7 Aug 2017, 04:21 last edited by 6thC 8 Jul 2017, 04:22
      #2

      @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
      
      1 Reply Last reply
      0

      1/2

      7 Aug 2017, 02:36

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved