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:
- Windows calls CreateProcess on the executable.
- The program gets copied (loaded) into working memory.
- 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