编译期断言
书中列出三种编译期断言的实现方式,一一列出:
CompileTimeAssertion.h
//第一个版本使用不能建立空数组的性质 #define STATIC_CHECK1(expr) \ {\ char unnamed[(expr) ? 1 : 0];\ } //第二个版本使用模板的非类形参,使用为定义类是违法的 template<bool> struct CompileTimeError;//声明一个模板 template<> struct CompileTimeError<true>{};//仅仅对模板参数为true的特化实现 #define STATIC_CHECK2(expr) \ (CompileTimeError<expr>()) //第三个版本,可以定制消息,但是这个消息必须是合法的c++标识符 template<bool> struct CompileTimeCheck { CompileTimeCheck(...){}//加上后面的{}还可以通过链接,但是仅仅是针对编译,声明就够了 }; template<> struct CompileTimeCheck<false>{}; #define STATIC_CHECK3(expr, msg) \ {\ struct ERROR_##msg{} unnameError;\ CompileTimeCheck<expr> unnameCheck(unnameError);\ }
CompileTimeAssertion.cpp
#include <iostream> #include "CompileTimeAssertion.h" int main() { /*****************版本1****************/ { STATIC_CHECK1(true); //.\CompileTimeAssertion.cpp(5) : error C2466: 不能分配常量大小为 0 的数组 //.\CompileTimeAssertion.cpp(5) : error C2133: “unnamed”: 未知的大小 //STATIC_CHECK(false); } /*****************版本2****************/ { STATIC_CHECK2(true); //error C2514: “CompileTimeError<__formal>”: 类没有构造函数 //STATIC_CHECK2(false); } /*****************版本3****************/ { STATIC_CHECK3(1 < 3, CompareTwoNumber); // error C2440: “初始化”: 无法从“main::ERROR_CompareTwoNumber”转换为“CompileTimeCheck<false>” //无构造函数可以接受源类型,或构造函数重载决策不明确 //STATIC_CHECK3(3 < 1, CompareTwoNumber); } }