静态断言
C++11中引入了static_assert关键字,用来实现编译时断言,称为静态断言。静态断言的语法格式如下所示:
static_assert(常量表达式, 提示字符串);
编译时首先检测“常量表达式”的值,若为真,则static_assert()不做任何操作,程序继续完成编译,若为假,产生一条编译错误,错误提示为静态断言中第二个参数给出的字符串信息。
C++11之前,C++中提供的assert()断言宏实现了运行时断言,这意味着不运行程序将无法检测到断言错误,对运行效率会有一定影响。另外运行时断言不会自动在断言位置停止下来等待调试,而是执行abort()直接终止程序,之后需要手动在发生断言的位置设置断点,重新调试,尤其对于C++中的模板来说,模板实例化是在编译阶段完成的,assert()断言不能在编译阶段完成对实例化模板的检测,C++11引入的static_assert()断言可以解决这个问题。
接下来通过一个案例说明静态断言的用法,如例1所示。
例1
1 #include <iostream>
2 using namespace std;
3 template <class T1, class T2>
4 void cpbybyte(T1& x, T2& y)
5 {
6 static_assert(sizeof(x) == sizeof(y), "the parameters must be the same width.");
7 }
8 int main()
9 {
10 int n;
11 char c;
12 cpbybyte(n, c);
13 return 0;
14 }
程序编译时出现错误,如图1所示。
图1 1 例1编译结果
例1中使用静态断言,在编译阶段测试两个待拷贝数据的字节数是否相同,若不相同,编译出错,错误提示是static_assert()中第二个参数给出的字符串信息。
需要注意的是,static_assert()断言表达式的结果,必须在编译阶段就可以计算出来,即必须是常量表达式。如果使用了变量则会导致错误,若有如下代码:
void set_age(const int n)
{
static_assert(n > 0, "The age should be greater than zero!");
}
上述代码中在static_assert()中使用了参数变量n,编译时提示“在静态断言中需要使用常量表达式”。对于这种情况,我们可以使用assert()宏在运行时对数据进行检测。