赞
踩
int Max(int a, int b) { return a > b ? a : b; }
int main() {
printf("%d\n", Max(123, 456));
return 0;
}
但是,如果我们还要比较更多的类型,例如char型,double型之类的,我们都需要重新写一个类似的实现,这很不方便:
char Max(char a, char b) { return a > b ? a : b; }
double Max(double a, double b) { return a > b ? a : b; }
int main() {
printf("%c, %lf\n", Max('a', 'z'), Max(1.1, 2.2));
return 0;
}
这个时候我们可以考虑使用模板来简化代码:
template <typename T>
T Max(T a, T b) { return a > b ? a : b; }
int main() {
printf("%d, %c, %lf\n", Max(123, 456), Max('a', 'z'), Max(1.1, 2.2));
return 0;
}
int Max_int(int a, int b) { return a > b ? a : b; }
char Max_char(char a, char b) { return a > b ? a : b; }
double Max_double(double a, double b) { return a > b ? a : b; }
int main() {
printf("%d, %c, %lf\n", Max_int(123, 456), Max_char('a', 'z'), Max_double(1.1, 2.2));
return 0;
}
首先,用前面的Max函数为例,先看一下我目前的写法风格吧:-P
需要注意的是:为防止宏嵌套出错,例如_Max(Pair(int, char))会被拓展成Max$_Pair(int, char)_$这样的不合法变量名(Pair的定义见1.1模板类示例),我们都需要多写一个类似于#define Max(T) _Max(T)这样的操作
#define _Max(T) Max$_##T##_$
#define Max(T) _Max(T)
#define _Max_IMPL(T) T Max(T)(T a, T b) { return a > b ? a : b; }
#define Max_IMPL(T) _Max_IMPL(T)
Max_IMPL(int);
Max_IMPL(char);
Max_IMPL(double);
int main() {
printf("%d, %c, %lf\n", Max(int)(123, 456), Max(char)('a', 'z'), Max(double)(1.1, 2.2));
return 0;
}
下面解释一下上面的代码到底做了什么:
用宏来模仿C++的写法 —— #define _Max(T) Max$_##T##_$
这里用了Max(T)宏来模仿C++的Max<T>写法。
例如:Max(int),宏拓展后实际上等于Max$_int_$($符号确实是合法变量名),这里用$_表示C++中模板的尖括号左侧<,用_$表示尖括号右侧>
模板实现 —— #define _Max_IMPL(T) T Max(T a, T b) { return a > b ? a : b; }
相当于C++的template <typename T> T Max(T a, T b) { return a > b ? a : b; }
实例化模板 —— Max_IMPL(int);
由于C不是C++,所以需要使用者自己去实例化对应的模板类型,此处宏拓展出来的代码为int Max(int)(int a, int b) { return a > b ? a : b; },然后Max(int)再拓展为Max$_int_$,于是最终结果为:
int Max$_int_$(int a, int b) { return a > b ? a : b; }
使用 —— Max(int)(123, 456)
相当于C++的Max<int>(123, 456)
像这样,我们就实现了一个T Max<T>(T, T)模板函数了!在此基础上,我们可以更进一步:如果能做一个检测代码中Max使用了哪些模板类型,然后在编译前自动添加实现Max_IMPL(…)完成“实例化”的程序,就可以完成类似于C++的模板类型推断功能了- -+
模板类同理,我们以简单的Pair为例(保存两个类型数据的结构)
#define _Pair(T1, T2) Pair$_##T1##_$$_##T2##_$ #define Pair(T1, T2) _Pair(T1, T2) #define _Pair_IMPL(T1, T2) typedef struct { T1 t1; T2 t2; } Pair(T1, T2) #define Pair_IMPL(T1, T2) _Pair_DEF(T1, T2) Pair_IMPL(int, char); Pair_IMPL(int, double); int main() { Pair(int, char) p_ic; Pair(int, double) p_id; p_ic.t1 = 123; p_ic.t2 = 'a'; p_id.t1 = 456; p_id.t2 = 1.1; return 0; }
#define _Pair(T1, T2) Pair$_##T1##_$$_##T2##_$Pair(T1, T2)模仿C++中Pair<T1, T2>的写法#define _Pair_IMPL(T1, T2) typedef struct Pair(T1, T2) { T1 t1; T2 t2; } Pair(T1, T2)template<typename T1, typename T2> struct Pair{ T1 t1; T2 t2; }Pair_IMPL(int, char);Pair<int, char>,此处宏拓展的最终结果为:typedef struct { int t1; char t2; } Pair$_int_$$_char_$Pair(int, char) p_ic;Pair<int, char> p_ic;像这样,我们就完成了简单的Pair<T1, T2>模板类了
个人项目(完善中):https://github.com/NumbFish-Luo/NfLib
参考资料:C语言宏高级用法 https://www.cnblogs.com/alantu2018/p/8465911.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。