gpt4 book ai didi

c++ - 寻找一个 MACRO 将两个字符加在一起用于 switch cases

转载 作者:行者123 更新时间:2023-11-30 02:45:41 24 4
gpt4 key购买 nike

我正在使用旧的网络引擎,通过网络发送的包类型由 2 个字节组成。

这或多或少是人类可读的形式,例如“LO”代表登录。

在读取数据的部分有一个巨大的开关,像这样:

short sh=(((int)ad.cData[p])<<8)+((int)ad.cData[p+1]);
switch(sh)
{
case CMD('M','D'):
..some code here
break

其中 CMD 是一个定义:

#define CMD(a,b) ((a<<8)+b)

我知道有更好的方法,但只是为了清理一下,并且能够更轻松地搜索标签(比如“LO”)(而不是搜索不同类型的“'L','O' "or "'L' , 'O'"or occasional "'L', 'O'"<- spaces make it hard to search) 我试图为开关制作一个宏,这样我就可以使用“LO”而不是定义,但我无法编译它。

问题来了:如何将 #define 更改为我可以像这样使用的宏:

case CMD("MD"):
..some code here
break

它最初是一个让生活更轻松的小子任务,但现在我无法摆脱它,感谢您的帮助!

干杯!

[edit] 代码有效,但世界错了! IE。 Visual Studio 2010 有一个与此相关的错误。难怪我会咬牙切齿。

最佳答案

基于宏的解决方案

string-literal 实际上是 char const[N] 的实例,其中 N 是字符串的长度,包括终止符空字节。考虑到这一点,您可以轻松访问 string-literal 中的任何字符,方法是使用 string-literal[idx] 指定您想要读取存储在偏移 idx

#define CMD(str) ((str[0]<<8)+str[1])

CMD("LO") => (("LO"[0]<<8)+"LO"[1]) => (('L'<<8)+'0')

然而,您应该记住,没有什么可以阻止您将上述宏与长度小于 2 的字符串一起使用,这意味着您可能会遇到 undefined-behavior 如果您尝试读取实际上无效的偏移量。


推荐:C++11,使用 constexpr 函数

您可以创建一个可用于constant-expressions 的函数(以及用于 case-labels 的函数),其参数为对 const char[3] 的引用,这是您的字符串文字 “FO”“真实” 类型。

constexpr short cmd (char const(&ref)[3]) {
return (ref[0]<<8) + ref[1];
}
int main () {
short data = ...;

switch (data) {
case cmd("LO"):
...
}
}

C++11user-defined literals

在 C++11 中,我们被授予了定义用户定义文字的可能性。这将使您的代码更易于维护和解释,并且使用起来更安全:

#include <stdexcept>

constexpr short operator"" _cmd (char const * s, unsigned long len) {
return len != 2 ? throw std::invalid_argument ("") : ((s[0]<<8)+s[1]);
}
int main () {
short data = ...;

switch (data) {
case "LO"_cmd:
...
}
}

case-label 关联的值必须通过常量表达式产生。看起来上面的代码可能会在运行时抛出异常,但由于 case-label 是常量表达式,编译器必须能够评估 "LO"_cmd 在翻译过程中。

如果这不可能,如在 "FOO"_cmd 中,编译器将发出诊断信息,指出代码格式错误。

关于c++ - 寻找一个 MACRO 将两个字符加在一起用于 switch cases,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24217964/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com