C++调用constexpr函数时GCC报错无法执行常量表达式问题
C++ constexpr函数形参编译错误解决
问题根源
- C++标准明确规定:函数的形参无论是否加const限定符、无论是否处于constexpr函数内,都不属于常量表达式。constexpr函数的语义是同时支持编译期、运行期两种调用场景,形参的值在运行期调用场景下是可变的,因此不能直接用形参去初始化constexpr变量——constexpr变量要求初始化值必须在编译期100%确定,不能依赖运行期可能变化的输入。
- 你的代码触发报错的直接逻辑是:调用
get_init_size时传入了形参args...,编译器需要校验args...属于常量表达式,才能将返回值用于初始化constexpr变量,但形参不满足常量表达式的要求,因此抛出了'args#0' is not a constant expression错误。 - 额外冗余点:你的
get_init_size只需要获取参数包的元素个数,完全不需要读取参数的值,直接通过模板参数包就能拿到对应数值,不需要传递函数参数。
修复方案
方案1:直接读取模板参数包长度(最推荐,完全规避形参问题)
template<typename ... Args> constexpr size_t get_init_size() { return sizeof...(Args); } template<typename ... Args> constexpr auto make_generic_header(Args ... args) { // 直接从模板参数包Args取长度,不依赖函数形参 constexpr size_t header_length = get_init_size<Args...>(); return header_length; } constexpr auto create_ipv4_header() { constexpr auto x = make_generic_header(0b01, 0b10, 0b01); return x; }
方案2:删除函数内不必要的constexpr中间变量定义
如果后续逻辑确实需要读取参数值做计算,可以把constexpr变量的定义移除,constexpr函数的返回值在编译期调用场景下会自动求值为常量:
template<typename ... Args> constexpr auto make_generic_header(Args ... args) { // 直接返回计算结果,不需要在函数内部声明constexpr变量 return get_init_size(args...); }
内容的提问来源于stack exchange,提问作者emik_g
相关产品推荐
相关产品推荐

