是不是常常使用assert?是否对你开发过程带来了便利?
void fun(TClass * p)
{
assert(p);
...
}
相信这样的代码不会陌生。但是,有没有想过,这个assert只能用于运行期,而对于编译期的错误就无能为力了。或者,你比较熟悉boost,对于BOOST_STATIC_ASSERT比较熟悉。有没有想过怎样实现编译期错误提示?
当我们写了错误的代码,编译器会给我们提示,错误信息各种各样。如果我们可以使用编译器的这种功能,我们人工特意的做出一些功能,让编译器来识别,并且,还可以让编译器提示出错。
实现这种功能,可以借助于模板,借助于模板的特化功能。下面来看看Loki是如何做的:
首先,声明一个模板类:
template<int> struct CompileTimeError;
仅仅是声明,并没有进行定义。
下面进行特化
template<> struct CompileTimeError<true> {};
这样,就有了一个CompileTimeError<true>类型的结构体定义。关键的代码来了:
#define LOKI_STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
其中,((expr) != 0返回一个bool值,这个值在编译器是可以确定的。如果值为true,那么顺利编译通过;如果为false,由于我们并没有定义CompileTimeError<false>结构,编译器无法找到匹配的类型,编译无法通过。编译器错误可能如下:error : 'ERROR_TEST' uses undefined struct 'CompileTimeError<__formal>'。
模板作为C++一个重要组成部分,在平时开发中用的还很少,以后应该有效的使用起来。