这里有很多评论试图区分宏和模板。
是的 - 它们都是同一件事:代码生成工具。
宏是一种原始形式,没有太多的编译器强制执行(就像在 C 中做 Objects - 它可以完成,但它并不漂亮)。模板更高级,并且有更好的编译器类型检查、错误消息等。
然而,每个人都有对方没有的优势。
模板只能生成动态类类型——宏可以生成几乎任何你想要的代码(除了另一个宏定义)。宏对于将结构化数据的静态表嵌入到代码中非常有用。
另一方面,模板可以完成一些用宏无法实现的真正 FUNKY 的事情。例如:
template<int d,int t> class Unit
{
double value;
public:
Unit(double n)
{
value = n;
}
Unit<d,t> operator+(Unit<d,t> n)
{
return Unit<d,t>(value + n.value);
}
Unit<d,t> operator-(Unit<d,t> n)
{
return Unit<d,t>(value - n.value);
}
Unit<d,t> operator*(double n)
{
return Unit<d,t>(value * n);
}
Unit<d,t> operator/(double n)
{
return Unit<d,t>(value / n);
}
Unit<d+d2,t+t2> operator*(Unit<d2,t2> n)
{
return Unit<d+d2,t+t2>(value * n.value);
}
Unit<d-d2,t-t2> operator/(Unit<d2,t2> n)
{
return Unit<d-d2,t-t2>(value / n.value);
}
etc....
};
#define Distance Unit<1,0>
#define Time Unit<0,1>
#define Second Time(1.0)
#define Meter Distance(1.0)
void foo()
{
Distance moved1 = 5 * Meter;
Distance moved2 = 10 * Meter;
Time time1 = 10 * Second;
Time time2 = 20 * Second;
if ((moved1 / time1) == (moved2 / time2))
printf("Same speed!");
}
该模板允许编译器动态地创建和使用模板的类型安全实例。编译器实际上在编译时进行模板参数数学运算,为每个唯一结果创建单独的类。有一个隐含的 Unit<1,-1>(距离 / 时间 = 速度)类型,它在条件内创建和比较,但从未在代码中显式声明。
显然,大学里有人用 40 多个参数(需要参考)定义了这种模板,每个参数代表不同的物理单元类型。考虑一下那种类的类型安全,只是为了你的数字。