这里有很多评论试图区分宏和模板。
是的,它们都是同样的东西:代码生成工具。
宏是一种原始形式,没有太多的编译器强制执行(就像在 C 中使用对象一样 - 可以做到,但不好看)。 模板更先进,并且具有更好的编译器类型检查、错误消息等功能。
然而,每种方法都有其优点。
模板只能生成动态类类型 - 宏可以生成几乎任何你想要的代码(除了另一个宏定义)。 宏非常有用,可以将结构化数据的静态表嵌入到您的代码中。
另一方面,模板可以实现一些真正奇特的事情,这是宏所不能实现的。例如:
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多个参数的模板(需要参考),每个参数代表不同的物理单位类型。考虑一下这种类的类型安全性,仅就你的数字而言。