旧时代

假设有 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 函数最终会生成多少个函数模板实例?