C++无模板化类型别名的替代方案:简化类模板传参
模板模板参数的简化使用方案
假设某库包含如下类模板A和B:
template <template <class> class T> class A; template <class T, class U> class B;
用户原本需要通过类型别名,固定B的部分参数后才能传入A:
template <class T> using C = B<T, UserType>; A<C> a{};
但当B存在大量模板参数时,每次定义冗长的类型别名会非常繁琐。我们可以通过模板参数绑定包装器实现简化用法,同时保留原有使用方式,且无需拆分A。
实现思路
核心是定义一个辅助结构,用来绑定模板的部分参数,再让A通过偏特化兼容这种绑定结构和原始的模板模板参数。
具体代码实现
// 标记类,用于区分绑定后的模板包装类型 struct BoundTemplateTag {}; // 模板绑定器:保存目标模板和固定参数 template <template <class...> class Tmpl, class... FixedArgs> struct BoundTemplate : BoundTemplateTag { // 生成绑定后的模板:补全剩余参数 template <class... Args> using Type = Tmpl<Args..., FixedArgs...>; }; // 主模板A,留空用于偏特化 template <typename T> class A; // 原有逻辑:兼容原始模板模板参数 template <template <class> class T> class A<T> { // 这里是A的原有实现代码 }; // 扩展逻辑:兼容绑定后的模板包装类型 template <template <class...> class Tmpl, class... FixedArgs> class A<BoundTemplate<Tmpl, FixedArgs...>> : public A<BoundTemplate<Tmpl, FixedArgs...>::template Type> { // 直接继承原有A的实现,复用全部逻辑 }; // 便捷的绑定工具:生成BoundTemplate实例 template <template <class...> class Tmpl, class... FixedArgs> constexpr auto bind_template = BoundTemplate<Tmpl, FixedArgs...>{};
用户使用方式
- 保留原有用法:
template <class T> using C = B<T, UserType>; A<C> a{};
- 简化用法(C++11及以上可用):
// 直接绑定B的部分参数传入A A<decltype(bind_template<B, UserType>)> a{};
如果觉得decltype不够简洁,可以封装一个宏:
#define BIND_TMPL(Tmpl, ...) decltype(bind_template<Tmpl, __VA_ARGS__>) // 用户调用更直观 A<BIND_TMPL(B, UserType)> a{};
关键说明
C++不允许直接定义template <class UserType> using D = template <class T> B<T, UserType>;这类指向模板模板参数的别名模板,因为别名模板只能指向具体类型或模板实例,无法直接指代模板本身。而上面的方案通过包装结构间接实现了“绑定部分参数后传递模板”的效果。
内容的提问来源于stack exchange,提问作者lobelk
相关产品推荐
相关产品推荐

