C++ static_assert报非常量表达式错误,返回constant实例为何可编译?
问题核心原因
这个差异本质是由两类返回值在常量表达式求值时的不同规则决定的:
1. 返回true__报错的原因
static_assert要求操作数必须是合法的常量表达式:
- 此时
push返回bool类型,registryv2<0>::x的推导类型就是普通bool,既没有constexpr修饰,也没有const修饰。 - 普通非const、非constexpr变量的值属于运行期状态,读取其值的操作默认不允许出现在常量表达式中。而且
push本身未声明为constexpr,就算x加了const修饰,初始化器push()也不是常量表达式,无法完成常量初始化,依然不能在static_assert中使用。
2. 返回true_编译通过的原因
此时push返回constant<true>类型,registryv2<0>::x的推导类型就是constant<true>,满足以下规则:
static_assert需要布尔值,会自动触发constant<true>的用户定义转换函数constexpr operator auto(),这个转换函数本身是符合常量表达式要求的。- 该转换函数的返回值完全来自类的模板参数
x(也就是编译期确定的true),没有任何读取对象运行期存储的操作。哪怕registryv2<0>::x本身不是constexpr变量,这个转换操作的结果也可以在编译期确定,符合static_assert的常量要求。
内容的提问来源于stack exchange,提问作者OwnageIsMagic
相关产品推荐
相关产品推荐

