改写参数包:替换可变参数模板中的指定类型
实现C++参数包的类型替换
这是个典型的类型元编程场景,咱们可以通过递归展开参数包+单个类型匹配替换的方式来实现你要的功能。下面是完整的可编译实现:
#include <string> #include <tuple> #include <type_traits> // 辅助元函数:处理单个类型的替换逻辑 template <typename From, typename To, typename T> struct ReplaceSingle { // 默认情况:不替换,返回原类型 using type = T; }; // 特化版本:当当前类型等于要替换的From时,返回To template <typename From, typename To> struct ReplaceSingle<From, To, From> { using type = To; }; // 主模板:负责展开参数包并应用替换 template <typename From, typename To> struct TermRewrite { // 接收参数包,返回替换后的类型组成的tuple(用来承载类型包) template <typename... Args> static auto constexpr eval() { return std::tuple<typename ReplaceSingle<From, To, Args>::type...>{}; } // 可选:直接返回类型别名,更适合获取类型而非对象 template <typename... Args> using EvalType = std::tuple<typename ReplaceSingle<From, To, Args>::type...>; }; int main() { // 方式1:通过对象获取类型 auto result = TermRewrite<int, char>::eval<int, std::string, double>(); // 静态断言验证结果是否符合预期 static_assert(std::is_same_v<decltype(result), std::tuple<char, std::string, double>>); // 方式2:直接获取类型别名 using ResultType = TermRewrite<int, char>::EvalType<int, std::string, double>; static_assert(std::is_same_v<ResultType, std::tuple<char, std::string, double>>); }
代码解释
ReplaceSingle元函数:这是核心的替换逻辑单元。默认模板会原样返回输入类型;特化版本会在输入类型等于From时,返回To类型,完成单个类型的替换。TermRewrite主模板:eval()方法:接收可变参数包Args...,对每个参数应用ReplaceSingle,然后把替换后的类型打包成std::tuple返回。你可以通过decltype从返回对象中提取最终的类型包。EvalType类型别名:更直接的方式,直接生成替换后的类型组成的tuple类型,不需要创建对象。
- 静态断言:用来验证替换结果是否符合预期,确保代码逻辑的正确性。
如果你的需求只是获取替换后的类型包而非创建对象,EvalType会更高效,因为它完全是编译期计算,没有运行时开销。
内容的提问来源于stack exchange,提问作者meguli
相关产品推荐
相关产品推荐

