LLVM15.0.1下std::format/fmt::format常量表达式错误排查
问题分析与解决
核心原因
LLVM 15.0.1对C++20 consteval 函数的参数检查比LLVM 12严格得多。std::format 和 fmt::format 的格式字符串参数都要求是编译期常量,但你的代码中用 xorstr_() 解密后的字符串是运行时生成的,不属于编译期常量,因此触发了"不是常量表达式"的错误。
解决方案
方案1:将xorstr_改为constexpr实现
如果你的字符串解密逻辑可以在编译期完成,修改 xorstr_ 为 constexpr 函数,让解密后的字符串成为编译期常量,这样就能直接兼容 std::format 和 fmt::format。
方案2:改用运行时格式化接口
如果无法修改 xorstr_,可以使用不要求格式字符串是编译期常量的格式化方法:
用fmt库的vformat接口(推荐)
fmt::vformat 是fmt库提供的运行时格式化入口,支持传入运行时生成的格式字符串:
m_state.script_file( ( std::filesystem::path{ xorstr_( "magma/luas" ) } /= name ).string(), [ & ] ( lua_State* const state, sol::protected_function_result result ) { if ( !result.valid() ) valve::g_cvar->con_print( false, 0xff0000ffu, fmt::vformat(xorstr_( "can't load {}, reason: {}.\n" ), fmt::make_format_args(name, sol::error{ result }.what())).data() ); return result; } );
用传统的std::stringstream
如果不想依赖fmt库的额外接口,也可以用C++标准库的stringstream:
m_state.script_file( ( std::filesystem::path{ xorstr_( "magma/luas" ) } /= name ).string(), [ & ] ( lua_State* const state, sol::protected_function_result result ) { if ( !result.valid() ) { std::stringstream ss; ss << xorstr_( "can't load " ) << name << xorstr_( ", reason: " ) << sol::error{ result }.what() << xorstr_( ".\n" ); valve::g_cvar->con_print( false, 0xff0000ffu, ss.str().data() ); } return result; } );
内容的提问来源于stack exchange,提问作者Jerry Ho
相关产品推荐
相关产品推荐

