C++ 中的 switch/case 语句具有 QString 类型
我想在程序中使用 switch-case,但编译器给出了此错误:
switch expression of type 'QString' is illegal
How can I use the switch
statements with a QString
?
我的代码如下:
bool isStopWord( QString word )
{
bool flag = false ;
switch( word )
{
case "the":
flag = true ;
break ;
case "at" :
flag = true ;
break ;
case "in" :
flag = true ;
break ;
case "your":
flag = true ;
break ;
case "near":
flag = true ;
break ;
case "all":
flag = true ;
break ;
case "this":
flag = true ;
break ;
}
return flag ;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
您可以在迭代之前创建一个 QStringList,如下所示:
然后:
You can, creating an QStringList before iteration, like this:
Then:
你不能。在 C++ 语言中
switch
语句只能与整型或枚举类型一起使用。您可以正式将类类型的对象放入switch
语句中,但这仅意味着编译器将查找用户定义的转换以将其转换为整型或枚举类型。You can't. In C++ language
switch
statement can only be used with integral or enum types. You can formally put an object of class type into aswitch
statement, but that simply means that the compiler will look for a user-defined conversion to convert it to integral or enum type.@DomTomCat 的回答已经谈到了这一点,但由于问题是专门询问 Qt 的,所以有更好的方法。
Qt 已经有 QString 的散列函数,但不幸的是 Qt4 的 qHash 不符合 constexpr 资格。幸运的是,Qt 是开源的,因此我们可以将 QStrings 的 qHash 功能复制到我们自己的 constexpr 哈希函数中并使用它!
Qt4的qHash源
我已修改它只需要一个参数(字符串文字总是以 null 结尾):
一旦定义了它,您就可以在 switch 语句中使用它,如下所示:
由于此方法使用 Qt 用于计算哈希值的相同代码,因此它将具有与QHash相同的哈希碰撞抵抗力,总体来说非常好。缺点是这需要一个相当新的编译器——因为它在 constexpr 哈希函数中有非返回语句,所以它需要 C++14。
@DomTomCat's answer already touched on this, but since the question is specifically asking about Qt, there is a better way.
Qt already has a hashing function for QStrings, but unfortunately Qt4's qHash is not qualified as a constexpr. Luckily Qt is open source, so we can copy the qHash functionality for QStrings into our own constexpr hashing function and use that!
Qt4's qHash source
I've modified it to only need one parameter (string literals are always null-terminated):
Once you've defined this, you can use it in switch statements like so:
Since this method uses the same code Qt uses to calculate hashes, it will have the same hash collision resistance as QHash, which is generally very good. The downside is that this requires a fairly recent compiler--since it has non-return statements in the constexpr hashing function, it requires C++14.
在 C++ 中不可能直接切换字符串。然而在Qt中可以使用
QMetaEnum
如下所示:Q_ENUM
以及如何开启一个字符串。您甚至不需要像 Anthony Hilyard 的答案中那样使用 C++14,并且匹配的情况不是字符串的哈希值,因此哈希冲突的可能性为零基本上
QMetaEnum
可以从字符串转换为枚举值,反之亦然,因此我们将使用它跳转到正确的分支。一个小限制是字符串是枚举值,因此字符串必须是有效的 C++ 标识符。但这很容易解决,只需在必要时用特定规则替换特殊字符即可。为此,首先声明一个枚举,并将在 switch case 中使用的字符串作为枚举器类声明中的名称。然后使用
Q_ENUMS
将枚举添加到元数据中,以便程序稍后进行搜索。然后使用 SwitchString 中实现所需的开关="nofollow noreferrer">
QMetaEnum::keyToValue
。比较区分大小写,因此如果您想要不区分大小写的搜索,请先将输入字符串转换为大写/小写。您还可以对字符串进行其他必要的转换。例如,如果您需要在 C++ 标识符中切换带有空格或禁止字符的字符串,您可以转换/删除/替换这些字符以使字符串成为有效的标识符。
然后只需使用该类来切换字符串即可。例如:
It's not possible to switch directly on strings in C++. However it's possible in Qt using
QMetaEnum
as shown here:Q_ENUM
and how to switch on a string. You don't even need C++14 like in Anthony Hilyard's answer, and the matching cases are not the hashes of the strings so there's zero chance of hash collisionBasically
QMetaEnum
can convert from string to enum value and vice versa so we'll use that to jump to the correct branch. One small limitation is that strings are enum values so the string must be a valid C++ identifier. But that's easy to workaround, just replace the special characters with a specific rule if necessaryTo do that, first declare an enum with the strings to be used in switch cases as enumerator name in your class declaration. Then add the enum to the metadata with
Q_ENUMS
in order for the program to search later.Then just implement the needed switch inside
SwitchString
after converting the string to the corresponding value withQMetaEnum::keyToValue
.The comparison is case sensitive so if you want a case insensitive search, convert the input string to upper/lower case first. You can also do other transformations necessary to the string. For example in case you need to switch strings with blank spaces or forbidden characters in C++ identifiers, you may convert/remove/replace those characters to make the string a valid identifier.
Then just use the class for switching the strings. For example:
如果您可以使用现代 C++ 编译器,那么您可以计算字符串的编译时哈希值。在这个答案中,有一个相当简单的
constexpr
哈希函数的示例。因此,解决方案可以如下所示:
它仍然不是一个完美的解决方案。可能会出现哈希冲突(因此,每当添加/更改
case
时都要测试您的程序),并且在从QString
到char*utf
字符。对于 c++ 11,请将
CONFIG += c++11
添加到您的项目中,对于 Qt5。 Qt4:QMAKE_CXXFLAGS += -std=c++11
If you can use a modern C++ compiler then you could compute a compile time hash value for your strings. In this answer there's an example of a rather simple
constexpr
hashing function.So a solution can look like this:
It is still not a perfect solution. There can be hash collisions (hence test your program whenever you add/change
case
) and you have to be careful in the conversion fromQString
tochar*
if you want to use exotic orutf
characters, for instance.For c++ 11 add
CONFIG += c++11
to your project, for Qt5. Qt4:QMAKE_CXXFLAGS += -std=c++11
如前所述这不是 Qt 问题,switch 语句只能使用常量表达式,看看集合类
QSet
是一个很好的解决方案As previously noted this is not a Qt problem, switch statements can only use constant expressions, look at the collection classes a
QSet
is a good solution试试这个:
如何使用:
有一些简单的宏魔法。预处理后:
将像这样工作:
try this:
how to use:
there is some simple macro magic. after preprocessing this:
will work like this:
我不知道qt,但你可以尝试一下。如果
QString
与正常的std::string
没有什么不同,您可以避免switch
并直接使用==
进行比较代码>.I am not aware of qt, but you can give this a try. You can avoid
switch
and directly use==
for comparison, ifQString
is no different than a normalstd::string
.恕我直言,这似乎更理智一些。
This seems a little saner IMHO.
我建议使用if和break。这将使其在计算中接近切换情况。
I would suggest to use if and break. This would make it near to switch case in the computation.
晚会了,这是我前一段时间提出的一个解决方案,它完全遵守所要求的语法并适用于 c++11 及以上版本。
唯一需要注意的区别是使用
switch
代替switch
和ucase
代替case
, ucase 值周围的括号(必需的,因为这是一个宏)。代码如下: https://github.com/falemagn/uberswitch
Late to the party, here's a solution I came up with some time ago, which completely abides to the requested syntax and works with c++11 onwards.
The only differences to be noticed are the usage of
switch
in place ofswitch
anducase
instead ofcase
, with the parenthesis around theucase
value (needed, baucause that's a macro).Here's the code: https://github.com/falemagn/uberswitch
这与 Qt 无关,就像与你袜子的颜色无关一样。
C++ switch 语法如下:
如果这没有帮助,请详细列出错误消息,可能还有您袜子的颜色。
编辑:要回复您的回复,您不能将
switch
与非整数类型一起使用。特别是,您不能使用类类型。不是QString
类型的对象,也不是任何其他类型的对象。您可以改用if-else if-else
构造,也可以使用运行时或编译时多态性、重载或任何switch
的替代方案。This has nothing to do with Qt, just as it has nothing to do with the colour of your socks.
C++ switch syntax is as follows:
If that doesn't help then please list in detail the error message, possible along with the colour of you socks.
Edit: to respond to your reply, you can't use
switch
with none-integral types. In particular, you can't use class types. Not objects of typeQString
and not objects of any other type. You can use anif-else if-else
construct instead, or you can use runtime or compile time polymorphism, or overloading, or any of the array of alternatives to aswitch
.看看这个,它对我有帮助
Check out this, it helps me
它与 C++ switch 语句相同。
It is identical to a C++ switch statement.