如何在if constexpr的单个分支中实现仅该分支触发的静态断言?
C++
if constexpr分支断言问题的解决方案 问题根源
原代码里的if constexpr条件a == 1是非模板依赖的常量表达式,按照C++标准,这种情况下编译器会检查所有分支的语法和常量表达式有效性——哪怕条件为真的分支会被执行,else分支里的代码也逃不过编译检查,这就是static_assert被触发的原因。
解决方法
要让static_assert仅在else分支生效,必须让if constexpr的条件依赖模板参数,这样编译器才会按照规则丢弃不成立的分支。以下是两种可行方式:
方式一:将函数改为模板函数
给函数添加默认模板参数,让判断条件依赖这个参数:
enum { a = 1, b = 2 - a}; template<int CheckVal = a> void foo() { if constexpr(CheckVal == 1) { } else { static_assert(b != 1, "fail :-("); } }
此时CheckVal是模板参数,if constexpr的条件依赖模板逻辑,当CheckVal=1时,else分支会被完全丢弃,里面的断言不会被编译器检查。
方式二:用模板包装常量
如果不想修改函数为模板,可以用一个简单的模板结构体包装常量,让判断表达式变成模板依赖的:
template<typename T, T Val> struct DepConstant { static constexpr T value = Val; }; enum { a = 1, b = 2 - a}; void foo() { if constexpr(DepConstant<int, a>::value == 1) { } else { static_assert(b != 1, "fail :-("); } }
这里DepConstant<int, a>::value属于模板依赖的表达式,if constexpr会正确丢弃不成立的分支,断言也就不会被触发。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

