如何实现模板成员别名及带部分实参的模板别名?
实现模板成员别名与部分模板实参绑定的两种方式
刚好最近也在折腾这类C++模板技巧,给你整理清楚两种实现方式,直接看代码和解释就行:
1. 将模板成员别名指向另一模板成员(函数指针形式)
先看基础的通用转换函数模板,它接受类型T和一个符合ConvertFunction<T>约束的转换函数F:
template <typename T, ConvertFunction<T> F> Result<> Convert(Chain& chain, T& field) { // ... 业务实现代码 }
接下来我们可以定义模板化的函数指针,把它绑定到已经填好部分模板实参的Convert实例上,比如绑定HexTo<T>作为转换函数:
template <typename T> constexpr Result<> (*ConvertHex)(Chain& chain, T& field) = &Convert<T, HexTo<T>>;
这样做的好处是,后续调用的时候不用再手动传HexTo<T>这个参数了,直接用ConvertHex<int>(chain, my_int)就能调用绑定好十六进制转换逻辑的Convert函数,相当于给通用模板做了一个"预配置"的别名。
2. 将模板别名替换为带有部分模板实参的模板(纯别名形式)
如果想用C++的using模板别名来实现类似的部分实参绑定,分两种情况:
针对函数模板的别名
因为函数模板本身不能直接用using别名,我们可以先定义函数指针类型的模板别名,再绑定具体实例:
// 先定义函数指针类型的模板别名 template <typename T> using ConvertDecPtr = Result<> (*)(Chain& chain, T& field); // 再绑定带部分实参的Convert实例 template <typename T> constexpr ConvertDecPtr<T> ConvertDec = &Convert<T, DecTo<T>>;
针对类模板的别名
如果是类模板的话就更简单了,直接用using把部分模板实参固定住:
// 假设原有类模板是这样 template <typename T, typename Converter> class GenericConverter { /* ... */ }; // 定义绑定了DecTo<T>的模板别名 template <typename T> using DecimalConverter = GenericConverter<T, DecTo<T>>;
注意事项
- 这种写法需要C11及以上版本支持,
constexpr函数指针的支持在C11就已经有了 ConvertFunction<T>应该是一个概念(C++20+)或者函数指针类型别名,用来约束第二个模板参数的合法性- 要确保
HexTo<T>、DecTo<T>这些转换函数符合ConvertFunction<T>的要求,能和Convert模板正确配合
内容的提问来源于stack exchange,提问作者Michał Fita
相关产品推荐
相关产品推荐

