简体   繁体   中英

How to write a switch statement for strings in Qt?

I need to create the equivalent of a switch/case statement for strings in C++ with Qt. I believe that the simplest way is something like this (pseudo code)

enum colours { red, green, blue };
QString array[] colour_names = { "red", "green", "blue" };
switch (color_names[user_string]) {
  case red: answer="Chose red";
  case green: answer="Chose green";
  case blue: answer="Chose blue";
  other: answer="Invalid choice";
}

But this doesn't take advantage of some of the features of Qt. I've read about QStringList's (to find the position of the string in a list of strings), and std:map (see How to easily map c++ enums to strings which I don't fully understand).

Is there a better way to do a switch on strings?

The only way to use switch() with strings is to use an integer-valued hash of a string. You'll need to precompute hashes of the strings you're comparing against. This is the approach taken within qmake for reading visual studio project files, for example.

Important Caveats:

  1. If you care about hash collisions with some other strings, then you'll need to compare the string within the case. This is still cheaper than doing (N/2) string comparisons, though.

  2. qHash was reworked for QT 5 and the hashes are different from Qt 4.

  3. Do not forget the break statement within your switch. Your example code missed that, and also had nonsensical switch value!

Your code would look like the following:

#include <cstdio>
#include <QTextStream>

int main(int, char **)
{
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
    static const uint red_hash = 30900;
    static const uint green_hash = 7244734;
    static const uint blue_hash = 431029;
#else
    static const uint red_hash = 112785;
    static const uint green_hash = 98619139;
    static const uint blue_hash = 3027034;
#endif

    QTextStream in(stdin), out(stdout);
    out << "Enter color: " << flush;
    const QString color = in.readLine();
    out << "Hash=" << qHash(color) << endl;

    QString answer;
    switch (qHash(color)) {
    case red_hash:
        answer="Chose red";
        break;
    case green_hash:
        answer="Chose green";
        break;
    case blue_hash:
        answer="Chose blue";
        break;
    default:
        answer="Chose something else";
        break;
    }
    out << answer << endl;
}
QStringList menuitems;
menuitems << "about" << "history";

switch(menuitems.indexOf(QString menuId)){
case 0:
    MBAbout();
    break;
case 1:
    MBHistory();
    break;
}

我在另一个站点上发现了一个使用QStringList颜色的建议,在switch中使用IndexOf(),然后在case语句中使用枚举值

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM