如何在 Qt 中为字符串编写 switch 语句?

2022-01-19 00:00:00 dictionary qt switch-statement c++

我需要使用 Qt 为 C++ 中的字符串创建等效的 switch/case 语句.我相信最简单的方法是这样的(伪代码)

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";
}

但这并没有利用 Qt 的某些特性.我已经阅读了 QStringList(在字符串列表中查找字符串的位置)和 std:map(参见 如何轻松地将 c++ 枚举映射到我不完全理解的字符串.

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?

推荐答案

对字符串使用 switch() 的唯一方法是使用字符串的整数值散列.您需要预先计算要比较的字符串的哈希值.例如,这是 qmake 中用于读取 Visual Studio 项目文件的方法.

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.

重要提示:

  1. 如果您关心与其他字符串的哈希冲突,那么您需要比较案例中的字符串.不过,这仍然比进行 (N/2) 字符串比较便宜.

  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.

qHash 针对 QT 5 进行了重新设计,哈希值与 Qt 4 不同.

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

不要忘记开关中的 break 语句.您的示例代码错过了这一点,并且还具有无意义的开关值!

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

您的代码如下所示:

#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;
}

相关文章