如何在C++任意嵌套层级的模板中替换指定类型?
如何在嵌套模板中递归替换指定类型?
我需要实现一个模板元函数the_ugly,把所有出现的the_bad类型替换成the_good,不管它嵌套在多少层模板里面,同时保留其他模板和参数不变。目前的实现只能处理顶层的the_bad,嵌套在std::vector、std::list这类模板里的the_bad没法替换,怎么修改?
原代码如下:
struct the_good {}; struct the_bad {}; template<typename T> struct the_ugly_impl { using type = T; }; template<> struct the_ugly_impl<the_bad> { using type = the_good; }; template<typename T> using the_ugly = typename the_ugly_impl<T>::type; // 能通过 static_assert(std::same_as<the_good, the_ugly<the_bad>>); // 无法通过 static_assert(std::same_as<std::vector<the_good>, the_ugly<std::vector<the_bad>>>); // 无法通过 static_assert(std::same_as<std::list<std::vector<the_good>>, the_ugly<std::list<std::vector<the_bad>>>>);
解决方案:递归遍历模板参数
要处理嵌套模板,需要给the_ugly_impl加一个针对任意模板类型的偏特化,递归处理每个模板参数,再重新生成原模板的实例。具体实现如下:
#include <vector> #include <list> #include <concepts> struct the_good {}; struct the_bad {}; // 基础特化:处理非模板类型,替换the_bad为the_good template<typename T> struct the_ugly_impl { using type = std::conditional_t<std::same_as<T, the_bad>, the_good, T>; }; // 偏特化:处理任意模板类型,递归处理每个模板参数 template<template<typename...> typename Template, typename... Args> struct the_ugly_impl<Template<Args...>> { using type = Template<typename the_ugly_impl<Args>::type...>; }; // 别名模板保持不变 template<typename T> using the_ugly = typename the_ugly_impl<T>::type; // 所有断言现在都能通过 static_assert(std::same_as<the_good, the_ugly<the_bad>>); static_assert(std::same_as<std::vector<the_good>, the_ugly<std::vector<the_bad>>>); static_assert(std::same_as<std::list<std::vector<the_good>>, the_ugly<std::list<std::vector<the_bad>>>>);
代码解释
- 基础特化:用
std::conditional_t直接判断当前类型是否是the_bad,是的话替换成the_good,否则保持原类型。 - 模板偏特化:匹配任意模板(比如
std::vector、std::list这类接受任意数量类型参数的模板),对每个模板参数Args...递归应用the_ugly_impl,然后用处理后的参数重新实例化原模板Template。 - 这种实现会自动递归处理所有嵌套层级的模板,不管嵌套多少层,只要里面有
the_bad都会被替换成the_good。
内容的提问来源于stack exchange,提问作者Guillaume Racicot
相关产品推荐
相关产品推荐

