目录
为什么我这里说“static_assert主要在编译时期起作用”?
(static_assert)当我们在编译阶段就满足了报错要求,会如何呢?
(assert) 当我们在运行阶段就满足了报错要求,会如何呢?
static_assert与assert
两者的异同点
形同的是两者均为“用于断言的宏操作”,但是static_assert主要在编译时期起作用,assert在运行时期起作用。两者均会给出错误的信息。
为什么我这里说“static_assert主要在编译时期起作用”?
Static_assert用于检查条件是否成立,如果成立就报错,错误指示内容为第二个参数位置上的字符串。但是static_assert在编译时期就已经开始起作用了,例如:在编译时期检查“函数的形参类型是否满足条件”,“函数的参数是否是我想要的指定数据类型”……等可以在编译时期就可以检查错误。还有当你的条件中包含着形参实例化后的一些值,比如“输入形参是否为1“……等必须依据输入形参才可以做报错决定的情况,static_assert也可以进行检错。编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算,但如果该常量表达式依赖于某些模板参数,则延迟到模板实例化时再进行演算,这就让检查模板参数成为了可能。
(static_assert)当我们在编译阶段就满足了报错要求,会如何呢?
代码示例:
#include <cassert>
#include <cstring>
using namespace std;
template <typename T, typename U> int bit_copy(T& a, U& b) {
//assert(sizeof(b) == sizeof(a));
static_assert(sizeof(b) == sizeof(a), "template parameter size no equal!");
memcpy(&a, &b, sizeof(b));
return 0;
};
int main()
{
int aaa = 0x2468;
double bbb;
bit_copy(aaa, bbb);
return 0;
}
输出结果:
输出结果显示“在编译阶段就会满足static_assert的报错条件从而报出错误“。
(assert) 当我们在运行阶段就满足了报错要求,会如何呢?
代码示例:
#include <cassert>
#include <cstring>
using namespace std;
template <typename T, typename U> int bit_copy(T& a, U& b) {
assert(sizeof(b) == sizeof(a)); // 仅仅是满足条件就报错
//static_assert(sizeof(b) == sizeof(a), "template parameter size no equal!"); // 报错提示更加的个性化
memcpy(&a, &b, sizeof(b));
return 0;
};
int main()
{
int aaa = 0x2468;
double bbb;
bit_copy(aaa, bbb);
return 0;
}
输出结果:
Static_assert相较于assert的优势
由于static_assert是编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。
assert是运行期断言,它用来发现运行期间的错误,不能提前到编译期发现错误,也不具有强制性,也谈不上改善编译信息的可读性,既然是运行期检查,对性能当然是有影响的,所以经常在发行版本中,assert都会被关掉;assert是运行期的判断,并且会强制终止程序,一般要求只能用于debug版本中,是为了尽可能快的发现问题。assert是要从release版本中去掉。所以一般开发会重新定义assert宏。
Static_assert在实例中的常用形式
Static_assert的出现,让对编译阶段,例如函数形参的数据类型等有了一定的约束,比如,我想禁止函数输入形参为int变量。