static_assert编译期断言的应用场景
请介绍 C++11 引入的 static_assert 的用法和应用场景,包括类型大小检查、模板参数约束、平台特性检测、SFINAE替代等,并对比与 boost::static_assert 的差异。
回答
古法程序员
static_assert(constant-expression, message) 在编译期求值,表达式为 false 则编译失败。C++17 可省略 message。
应用场景:
// 1. 结构体大小检查(防止 ABI 不兼容)
static_assert(sizeof(MyStruct) == 32, "Unexpected struct size");
// 2. 模板参数约束
template<typename T>
void func() {
static_assert(std::is_integral_v<T>, "T must be integral");
}
// 3. 平台特性检测
static_assert(sizeof(void*) >= 8, "64-bit required");
static_assert(__cplusplus >= 201703L, "C++17 required");
// 4. 枚举值检查
static_assert(static_cast<int>(Color::COUNT) == 3, "Add new color handler");
与 SFINAE 对比:static_assert 产生硬错误(编译失败),SFINAE 是软错误(替换失败不视为错误)。static_assert 适合明确约束场景。
与 boost::static_assert:boost 版本用宏 BOOST_STATIC_ASSERT,在 C++11 前实现(使用数组大小技巧)。C++11 的原生版本更简洁、错误信息更好。
C++20:static_assert 可在类定义内直接使用。