C++20常量类工厂函数:实现参数值的精准编译/运行时错误提示
问题需求
- 基于C++20实现常量/不可变类,通过工厂函数创建实例
- 工厂函数需校验参数
i的合法性(要求i >= 0) - 嵌入式项目限制:禁止使用异常
- 核心行为要求:
- 当
i为编译期常量时,非法值触发编译时错误,且错误信息需关联具体非法值 - 当
i为运行期变量时,非法值触发运行时错误
- 当
- 优先采用非模板实现方案
现有备选方案的局限性
- Option 1(
#error宏):无论参数合法与否都会触发编译错误,完全不可用 - Option 2(
consteval内调用非constexpr断言):编译错误信息无法关联i的具体值,排查困难 - Option 3(
constexpr内调用断言):编译期非法值会导致函数无法成为常量表达式,退化为运行时错误,不符合“常量参数编译时报错”的要求 - Option 4(模板类+
static_assert):依赖模板参数,违背“优先非模板”的需求 - Option 5(模板工厂函数+
static_assert):需要用户手动选择调用模板版/非模板版接口,使用体验差,无法自动适配常量/非常量参数
推荐实现方案
核心思路是通过单一工厂函数自动适配常量/非常量参数,借助C++20的std::is_constant_evaluated()(嵌入式编译器普遍支持)分支处理编译期与运行时逻辑:
#include <type_traits> // 嵌入式场景的运行时断言实现,替换原有Assert宏 #define RUNTIME_ASSERT(expr) do { if (!(expr)) { while(true); } } while(false) class ConstantClass { public: static constexpr ConstantClass create(int i) { if (std::is_constant_evaluated()) { // 编译期路径:常量参数非法时触发编译错误 if (i < 0) { static_assert(i >= 0, "Invalid constant value: i must be non-negative"); // 以下代码仅为语法占位,static_assert已在编译期阻断执行 throw; } } else { // 运行期路径:非常量参数非法时触发运行时断言 RUNTIME_ASSERT(i >= 0); } return ConstantClass(i); } private: constexpr ConstantClass(int i) { // 类构造实现 } }; // 测试用例 int main() { // 编译期错误:常量参数-1非法 // ConstantClass c1 = ConstantClass::create(-1); // 编译通过:常量参数合法 constexpr ConstantClass c2 = ConstantClass::create(5); // 运行期错误:非常量参数非法 int bad_val = -1; // ConstantClass c3 = ConstantClass::create(bad_val); // 运行期正常:非常量参数合法 int good_val = 10; ConstantClass c4 = ConstantClass::create(good_val); }
方案优势
- 自动适配参数类型:无需用户区分模板/非模板接口,单一
create()函数自动处理常量/非常量参数 - 精准错误反馈:
- 常量非法值:
static_assert会输出包含具体非法值的编译错误(不同编译器提示细节略有差异,但均关联i的取值) - 非常量非法值:触发嵌入式友好的运行时死循环断言,符合项目限制
- 常量非法值:
- 非模板实现:满足“优先非模板”的需求,代码简洁易用
- 标准兼容性:基于C++20标准特性
std::is_constant_evaluated(),主流嵌入式编译器(GCC、Clang、ARMCC等)均支持
注意事项
- 若编译器对
std::is_constant_evaluated()支持不足,可替换为编译器内置函数,如GCC/Clang的__builtin_is_constant_evaluated()、ARMCC的__is_constant_evaluated() - 运行时断言的实现可根据项目需求调整(如触发硬件中断、记录日志后死循环等),只要保证不使用异常即可
- 构造函数设为
constexpr private,确保只能通过工厂函数创建实例,保证类的不可变性
内容的提问来源于stack exchange,提问作者jgreen81
相关产品推荐
相关产品推荐

