如何编写支持字符串字面量或char模板参数的C++20包装函数
解决方案
要实现能同时适配字符串字面量和char模板参数的print_wrapped,核心是利用C++20的非类型模板参数推导和FixedString的推导指引,让包装函数自动匹配对应的print重载。
步骤1:定义FixedString及基础print函数
先补全必要的FixedString定义和原有的print重载:
#include <iostream> #include <string_view> #include <type_traits> // 定义FixedString结构 template<size_t N> struct FixedString { constexpr FixedString(const char (&str)[N]) noexcept { std::copy_n(str, N, value); } char value[N]; constexpr operator std::string_view() const noexcept { return {value, N-1}; } }; // 推导指引:让编译器从字符串字面量自动推导FixedString的模板参数N template<size_t N> FixedString(const char (&)[N]) -> FixedString<N>; // 处理FixedString的print重载 template<FixedString S> void print() { std::cout << "FixedString: " << S << '\n'; } // 处理char的print重载 template<char C> void print() { std::cout << "Char: '" << C << "'\n"; }
步骤2:实现单一版本的print_wrapped
通过auto非类型模板参数配合constexpr分支判断,实现单一版本的包装函数:
template<auto Arg> void print_wrapped() { if constexpr (std::is_same_v<decltype(Arg), char>) { // 分发到char类型的print print<Arg>(); } // 判断是否为const char[]类型的字符串字面量 else if constexpr (std::is_array_v<decltype(Arg)> && std::is_same_v<std::remove_const_t<std::remove_extent_t<decltype(Arg)>>, char>) { // 将字面量转换为FixedString后分发到对应print print<FixedString{Arg}>(); } }
测试调用
上述写法可以正确处理两种模板参数的调用:
int main() { print_wrapped<'X'>(); // 输出:Char: 'X' print_wrapped<"test_str">();// 输出:FixedString: test_str }
原理说明
- 对于
char类型模板参数,直接匹配对应的print重载; - 对于字符串字面量,借助FixedString的推导指引,编译器自动将
const char[N]转换为FixedString<N>类型,进而匹配到处理FixedString的print重载。
内容的提问来源于stack exchange,提问作者eyelash
相关产品推荐
相关产品推荐

