编译期间Assertions

来源:互联网 发布:百度云网络异常1 编辑:程序博客网 时间:2024/04/28 17:42

——2.1Compile-Time Assertions

其实,但从编译期assert得角度而言,我们不需要template技术就可以,但是,那样我们无法得到详细得出错信息:

#define        STATIC_CHECK(expr)    {char unnamed[(expr) ? 1 : 0];}
template    
<class To,class From>
To    safe_reinterpret_cast(From from)
{
    STATIC_CHECK(
sizeof(from) <= sizeof(To));
    
return    reinterpret_cast<To>(from);
}

 这里有三点需要注意:
1.大小为0得数组是非法的,不知道这个没有关系,你的编译器会提醒你,但是知道这个你的设计空间将被扩展。
2.我们可以正确assert,但是无法获取丰富的错误信息。如果有问题,编译期会提示你你试图产生一个长度为0得数组。其他没有什么了,这是我们不想看到的。
3.如果使用template,编译器会在错误信息里指出template得名字。

为了弥补第2点提到的问题,我们利用第3点的事实:

template<bool>    struct CompileTimeError;
template
<>    struct    CompileTimeError<true>{};
#define STATIC_CHECK(expr)    (CompileTimeError< (expr) != 0>())

注意这已经足够了,但是我们总想让事情变得更好:

#define    STATIC_CHECK(expr,msg)    
{
    
class ERROR_##msg{};
    (
void)sizeof( (CompileTimeErrorChecker<(expr)>(ERROR_##msg())) );
}

请注意这里没有什么,只是在出错的时候,定义了一个类,让后把这个类得一个对象传给CompileTimeErrorChecker<expr>得构造函数,试图构造一个对象,但这是不行的,并没有接受如此参数的构造函数(其实ERROR_##msg是个局部类,要是真的让CompileTimeErrorChecker<expr>知道这个类,反而是一件比较难的事),所以编译器会提示你说无法转换ERROR_##msg到CompileTimeErrorChecker<expr>,这太好了,编译器会显示你定制的信息。

原创粉丝点击