constexpr能否替代用于实例化模板且两次使用传入参数的宏?
解决方案
核心思路是利用C++的编译期常量推导特性,完全替代宏实现,同时保留你需要的一行式实例化写法,还能规避宏的各类副作用(比如参数重复求值、全局作用域污染等)。
方案1:C++20及以上(最简洁写法,使用用户定义字面量)
借助C++20支持字符串作为非类型模板参数的特性,用自定义字面量实现最简洁的调用方式:
#include <string> // 定义用户定义字面量运算符 template <std::fixed_string Str> constexpr auto operator""_pattern() { constexpr size_t word_num = wordCount(Str); return Pattern<word_num>(Str); }
使用时比原有宏写法更简洁:
auto pattern_a = " ? AA BB CC DD EE "_pattern; auto pattern_b = " ? AA BB CC DD EE "_pattern;
方案2:兼容C++17版本(使用模板辅助函数)
如果编译环境不支持C++20,可以用模板辅助函数+数组参数推导实现,完全兼容原有使用习惯:
#include <utility> #include <string_view> template <size_t StrLen, size_t... Idx> constexpr auto create_pattern_impl(const char (&str)[StrLen], std::index_sequence<Idx...>) { constexpr std::string_view sv{str, StrLen - 1}; // 剔除字符串末尾的\0结束符 constexpr size_t word_num = wordCount(sv); return Pattern<word_num>(sv); } template <size_t StrLen> constexpr auto createPattern(const char (&str)[StrLen]) { return create_pattern_impl(str, std::make_index_sequence<StrLen>{}); }
使用方式和原有宏几乎完全一致:
auto pattern_a = createPattern(" ? AA BB CC DD EE "); auto pattern_b = createPattern(" ? AA BB CC DD EE ");
两种方案的所有计算均在编译期完成,运行期开销和原有宏实现完全一致,同时具备完整的类型安全校验。
内容的提问来源于stack exchange,提问作者Luiz
相关产品推荐
相关产品推荐

