记录一个宏的使用技巧,使用宏生成一定规则的字符串

记录一个宏的使用技巧

背景

最近在项目中遇到一个问题,项目中一个字段对外的协议是毫无规律的整形值,内部需要将这个协议映射成方便处理的数据结构,想到的办法是把协议值先枚举出来,然后解析枚举变量。由于枚举变量本身不能直接解析,所以该为解析枚举变量的名字。比如

enum
{
	ONLY_TYPE1 = 1,
	ONLY_TYPE2 = 2,
	ONLY_TYPE3 = 3,
	ONLY_TYPE4 = 4,
	TYPE1_AND_TYPE2 = 5,
	TYPE1_AND_TYPE2_AND_TYPE3 = 6,
	TYPE1_AND_TYPE2_AND_TYPE3_AND_TYPE3 = 7,
};

只要保证枚举变量名字按照这种规律去命名,就可以去解析它。但是嘛,写代码吗,你就算在这里注释要这么写,也还是会出现就不看你注释来的情况,毕竟这种命名规则不能算是规范。所以呢,想通过自动生成变量名的方式强制约束,你不要自己去命名,按照我给的接口传参数就行了。

宏的使用

基本还是依靠宏连接符号##,因为参数数量是可变的,还要解析参数数量,这部分参考了这位大佬的代码,
https://blog.csdn.net/10km/article/details/80760533
基本思路是把各个参数数量的宏先定义出来,然后定义一个入口宏,根据参数数量再替换成相应的宏。
上代码,

//这个宏用来获取参数列表数量
#define ARG_COUNT(...) _ARG_COUNT_PRIVATE(0, ##__VA_ARGS__,\
	 9,  8,  7,  6,  5,  4,  3,  2,  1,  0)
#define _ARG_COUNT_PRIVATE(\
	_0,  _1,  _2,  _3,  _4,  _5,     \
    _6,  _7,  _8,  _9,  N, ...) N

//嵌套的宏不能展开,需要再定义一层
#define _CAT(x, y)      x##y
#define _NAME(TYPE)     #TYPE
#define _JOIN(A, B)     A##_##B
#define CAT(x, y)       _CAT(x, y)
#define NAME(TYPE)      _NAME(TYPE)
#define JOIN(A, B)      _JOIN(A, B)

//这些宏用来连接字符形成统一规范的命名
#define METHOD_CREATE(COMBINE, OLDMETHOD, NEWTYPE) JOIN(OLDMETHOD, JOIN(COMBINE, NEWTYPE))
#define METHOD1(TYPE) TYPE
#define METHOD2(COMBINE, TYPE) JOIN(COMBINE, TYPE)
#define METHOD3(COMBINE, TYPE1, TYPE2) METHOD_CREATE(COMBINE, METHOD1(TYPE1), TYPE2)
#define METHOD4(COMBINE, TYPE1, TYPE2, TYPE3) METHOD_CREATE(COMBINE, METHOD3(COMBINE, TYPE1, TYPE2), TYPE3)
#define METHOD5(COMBINE, TYPE1, TYPE2, TYPE3, TYPE4) METHOD_CREATE(COMBINE, METHOD4(COMBINE, TYPE1, TYPE2, TYPE3), TYPE4)
#define METHOD6(COMBINE, TYPE1, TYPE2, TYPE3, TYPE4, TYPE5) METHOD_CREATE(COMBINE, METHOD5(COMBINE, TYPE1, TYPE2, TYPE3, TYPE4), TYPE5)

//这个宏会根据参数数量去替换成上面的其中一个METHOND
#define METHOD(...) CAT(METHOD, ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)

using namespace std;
enum 
{
    METHOD(ONLY, TYPE1) = 1,
    METHOD(AND, TYPE1, TYPE2) = 5,
    METHOD(AND, TYPE1, TYPE2, TYPE3) = 6,
    METHOD(AND, TYPE1, TYPE2, TYPE3, TYPE4) = 7,
};

int main()
{
    cout << NAME(METHOD(ONLY, TYPE1)) << endl;
    cout << NAME(METHOD(AND, TYPE1, TYPE2)) << endl;
    cout << NAME(METHOD(AND, TYPE1, TYPE2, TYPE3)) << endl;
    cout << NAME(METHOD(AND, TYPE1, TYPE2, TYPE3, TYPE4)) << endl;
}

out>>>>
ONLY_TYPE1
TYPE1_AND_TYPE2
TYPE1_AND_TYPE2_AND_TYPE3
TYPE1_AND_TYPE2_AND_TYPE3_AND_TYPE4

非常简洁,新增值只要复制一下宏把参数填进去就行了,毕竟我都把复制粘贴模板给你了,你总不能还不按照这个来吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 同一个字符串使用JWT生成字符串是不一样的。JWT是一种将JSON数据编码为安全且紧凑的字符串的标准方法。JWT包含了头部信息、载荷信息和签名信息。其中载荷信息是用来存储用户的信息或者其他需要传输的数据的,而签名信息则是用来验证消息是否被篡改的。所以,即使两个字符串的内容相同,它们生成的JWT字符串也是不同的,因为JWT中包含了额外的信息。 ### 回答2: 同一个字符串使用JWT生成字符串不一样。JWT(JSON Web Token)是一种用于在网络应用间传递安全可靠的信息的一种方式,它由三部分组成,分别是头部、载荷和签名。其中,载荷部分存储了一些基本的信息,如用户ID、用户名等。而头部和载荷经过Base64编码后,再通过签名算法进行签名,生成了最终的JWT字符串。 对于同一个字符串来说,其生成的JWT字符串会因为签名算法的不同而产生不同的结果。签名算法通常使用HMAC(Hash-based Message Authentication Code)或RSA(Rivest-Shamir-Adleman)等加密算法,其处理方式都是将原始字符串与密钥进行运算,得到不同长度的签名结果。 由于JWT使用了签名算法进行加密,所以无论原始字符串是否相同,生成的JWT字符串都会不一样。即使是同一个字符串,如果使用不同的密钥生成JWT,其最终的字符串也会有所不同。这样可以确保每个JWT都具有唯一性,从而增加了安全性,防止被篡改。 总结来说,同一个字符串使用JWT生成字符串是不一样的,因为JWT对字符串进行了签名加密,使用了不同的密钥和算法,生成的JWT字符串都有所差异。 ### 回答3: 同一个字符串使用JWT生成字符串是不一样的。 JWT(JSON Web Token)是一种用于在网络应用间传递信息的编码规范。它由三部分组成:头部(header)、载荷(payload)和签名(signature)。 在JWT中,头部包含了用于指示当前数据使用的加密算法,例如HMAC SHA256或RSA。载荷包含了实际的数据,例如用户ID、用户名等信息。签名由头部、载荷和密钥生成,用于验证数据的完整性和真实性。 当对同一个字符串使用JWT生成字符串时,生成字符串是不一样的。这是因为JWT中的签名是由头部、载荷和密钥生成的,而密钥是保密的。即使使用相同的字符串作为载荷,但是不同的密钥会生成不同的签名,导致最终生成字符串也会不同。 同时,每次生成的JWT字符串还会包含当前时间等信息,这些信息也会导致生成字符串不一样。 因此,同一个字符串使用JWT生成字符串是不一样的。这也是JWT保证数据的安全性和真实性的一种方式,可以防止伪造和篡改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值