强制编译时约束
2008-03-27 21:40:35 来源:WEB开发网size_t nbytes = offsetof (S, mem);
该表达式以字节为单位返回成员 mem 的偏移量。按照 C++ 标准,S 必须是一个 POD 类(class),结构(struct)或者联合(union),否则,结果是不确定的。所以你的任务是编写一个约束,这个约束能在编译时自动区分 POD 和 非 POD 类型。一旦违反了“必须是一个 POD 类型”约束,编译器便会发出明确的出错信息。
实现约束
约束实际上就是在某个类模板的成员函数中的一个表达式或者是一个声明。当约束被违反后,上述的表达式便触发一个编译错误。具有挑战的地方是要找到正确的编译时表达式,在约束被违反时激活这些表达式。此时熟悉 C++ 标准当然是有益而无害的。标准中说非 POD 对象不能是一个联合(union)的成员(见标准的 clause 9.5)。利用这个限制,创建一个联合,让其唯一成员就是你要测试的对象不就行了。
template <class T> struct POD_test
{
POD_test()
{
union
{
T t; //T 必须是一个 POD 类型
} u;
}
};
编译器只为实际被调用的成员函数产生代码,或者显式或者隐式。因此,在某个类模板的构造函数或吸构函数中实现该约束将保证其编译时能处理其每个实例。(稍后我们将看到如何改进此设计)
为了测试这段代码,你可以使用各种不同的模版参数来进行实例化:
//下列三条语句通过编译
POD_test <int> pi;
POD_test <S1> ps1;
POD_test <S4> ps4;
//编译失败
POD_test <std::string> pstr;
POD_test <C1> pc1;
POD_test <C2> pc2;
正像我们期望的那样,由于后面三个实例其模板参数不是 POD 对象,编译器在处理时发出了出错信息。
更多精彩
赞助商链接