寻找一个宏添加两个字符在一起的开关情况
Looking for a MACRO adding two characters together for switch cases
我在一个旧的网络引擎上工作,通过网络发送的包类型由2字节组成。
这或多或少是人类可读的形式,例如"LO"代表Login。
在读取数据的部分有一个巨大的开关,像这样:
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'"或"'L','O'"或偶尔的"'L','O'"<-空格使其难以搜索)我试图为开关做一个宏,所以我可以使用"LO"代替定义,但我只是不能让它编译。
所以这里有一个问题:如何将#define更改为我可以像这样使用的宏:
case CMD("MD"):
..some code here
break
它开始作为一个小的子任务,使生活更容易一点,但现在我不能把它从我的头,谢谢任何帮助!
干杯!
[编辑]代码工作,它的世界是错的!ie。Visual Studio 2010在这方面有一个bug。
字符串字面值实际上是char const[N]
的一个实例,其中N
是字符串的长度,包括结束的空字节。考虑到这一点,您可以通过使用string-literal[idx]
指定您想要读取存储在偏移量idx
的字符来轻松访问字符串文字中的任何字符。
#define CMD(str) ((str[0]<<8)+str[1])
<一口>一口>
CMD("LO") => (("LO"[0]<<8)+"LO"[1]) => (('L'<<8)+'0')
你应该记住,没有什么可以阻止你使用上面的宏与长度小于2
的字符串,这意味着你可能会遇到未定义的行为如果你试图读取一个实际上无效的偏移量。
推荐: c++ 11,使用constexpr函数
您可以创建一个可以在常量表达式中使用的函数(并且在case-labels中使用),使用引用const char[3]的形参,这是您的string-literal " foo "的"real"类型。
constexpr short cmd (char const(&ref)[3]) {
return (ref[0]<<8) + ref[1];
}
int main () {
short data = ...;
switch (data) {
case cmd("LO"):
...
}
}
c++ 11和用户定义的字面值
在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
中,编译器将发出一个诊断,指出代码是病态的。
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 在将字符插入 2d 字符串时如何不显示空字符?
- 将图形属性与 std::unique_ptr 捆绑在一起
- 在定义字符数组(井字游戏)的 for 循环中应用输入限制
- 你能在 c++ 中将不同的数字类型加在一起吗?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 当返回语句时,逗号运算符、大括号初始化列表和 std::unique_ptr 组合在一起
- 防止控制台在通道字符(在 c++ 中)中输入空格(即空格、制表符和换行符)
- 为什么push_back和emplace_back结合在一起时,会有不同的行为
- 在浮点精度成为一个问题之前,可以将多少个浮点值加在一起
- 为什么在template函数广播中把两个extensor表达式加在一起不正确
- 实现具有浮点键的类似哈希表的数据结构,其中公差内的值被合并在一起
- 在C++中将字符向量转换为字符串向量
- 如何在避免字符行为的同时将 uint8_t 与 I/O 流一起使用?
- 通过字符串迭代并将每个循环中的先前字符组合在一起
- 如何加入两个指针以将其串在一起并将其存储在数组或字符中
- 将字符数组连接在一起
- 将字符比较在一起
- 在 c++ 中,char 和 const * char 有什么区别,为什么不能将两个字符加在一起
- 寻找一个宏添加两个字符在一起的开关情况