旧时代
假设有 val1,val2两个值,希望打印出来。直接的做法是:
PRINTF(“my log is val1=%d, val2=%d”, val1, val2);
这个代码的缺陷是:
- val1、val2要重复写两次,若变量更改,需要写两次。
- 如果 val1、val2 是字符串类型,则格式化方式要改变
- 如果 val1、val2 是对象类型,则无法直接用 PRINTF,需要预先手工把对象转成字符串,然后用 %s 打印
新科技
(例1)如果 val1=1024, val2=4096.5
LOG(“my log is”, K(val1), K(val2));
输出:
my log is val1=1024,val2=4096.5
(例2)如果 val1=”hello”, val2=true
LOG(“my log is”, K(val1), K(val2));
输出:
my log is val1=hello,val2=true
实现思路
假设最多处理 10 个 KV。用宏展开 + Template。一般来说,LOG 记录 10 个 KV 足够。如果需要处理更多 KV,多重复点宏展开代码即可。
定义 10 个函数
(为了降低工作量,可以用宏展开的方式来定义):
- my_print_1(info, char *key1, typename val1);
- my_print_2(info, char *key1, typename val1, char *key2, typename val2);
- my_print_3(info, char *key1, typename val1, char *key2, typename val2, char *key3, typename val3);
- ...
实现10个函数
对于my_print_n(info, ….)
- 根据 n 展开宏 BODY(n)
- BODY(1) = print(data_buf, key1, obj1)
- BODY(2) = BODY(1) + "," + print(data_buf, key2, obj2)
- BODY(3) = BODY(2) + "," + print(data_buf, key3, obj3)
- ...
实现 print(buf, char *key, T obj)
利用模板实现,基础数据类型直接匹配并输出,对象类型调用 to_string 方法输出到 buf。
具体落实到工程代码上还有一些细节,以上就是总体思路。
结尾
提个问题:my_print_10 函数最终会生成多少个函数模板实例?