如何缩减彼此紧密关联的模板参数以简化多参数模板函数调用?
这问题我太熟悉了!咱们核心思路就是把那些和FooX绑定死的Helper、Client、Server类型,直接和FooX本身挂钩,这样调用的时候只需要传一个FooX就行,再也不用重复写那一串关联类型了。下面给你几种实用的实现方式,你可以根据自己的代码场景选:
方法1:给FooX添加嵌套类型(最直接的方式)
如果FooX是你自己维护的类型,直接在里面定义对应的嵌套类型别名就行:
// 给每个FooX添加关联类型的嵌套别名 struct Foo1 { using Helper = Foo1Helper; using Client = Foo1Client; using Server = Foo1Server; }; struct Foo2 { using Helper = Foo2Helper; using Client = Foo2Client; using Server = Foo2Server; }; struct Foo3 { using Helper = Foo3Helper; using Client = Foo3Client; using Server = Foo3Server; }; // 修改原模板函数,只需要一个模板参数 template<typename T> void Func(void) { // 内部直接通过T的嵌套类型获取关联类型 using HelperType = typename T::Helper; using ClientType = typename T::Client; using ServerType = typename T::Server; // 这里写你的原有逻辑,比如实例化这些类型的对象、调用方法等 } // 调用瞬间简化! Func<Foo1>(); Func<Foo2>(); Func<Foo3>();
方法2:用模板特化建立关联(适合不能修改FooX的场景)
如果FooX是第三方库的类型,没法修改它的定义,那就用模板特化来建立FooX和关联类型的映射:
// 先定义一个空的关联模板 template<typename T> struct FooAssociations; // 为每个FooX特化这个模板,指定对应的关联类型 template<> struct FooAssociations<Foo1> { using Helper = Foo1Helper; using Client = Foo1Client; using Server = Foo1Server; }; template<> struct FooAssociations<Foo2> { using Helper = Foo2Helper; using Client = Foo2Client; using Server = Foo2Server; }; template<> struct FooAssociations<Foo3> { using Helper = Foo3Helper; using Client = Foo3Client; using Server = Foo3Server; }; // 修改模板函数,通过关联模板获取类型 template<typename T> void Func(void) { using HelperType = typename FooAssociations<T>::Helper; using ClientType = typename FooAssociations<T>::Client; using ServerType = typename FooAssociations<T>::Server; // 原有逻辑不变 } // 调用同样简洁 Func<Foo1>(); Func<Foo2>(); Func<Foo3>();
方法3:结合别名模板简化类型获取(C++11及以上)
如果觉得每次写typename FooAssociations<T>::XXX太啰嗦,可以用C++11引入的别名模板进一步简化:
// 先定义关联模板和特化(和方法2一样) template<typename T> struct FooAssociations; template<> struct FooAssociations<Foo1> { /* ... */ }; template<> struct FooAssociations<Foo2> { /* ... */ }; template<> struct FooAssociations<Foo3> { /* ... */ }; // 定义别名模板,让获取关联类型更直观 template<typename T> using FooHelper = typename FooAssociations<T>::Helper; template<typename T> using FooClient = typename FooAssociations<T>::Client; template<typename T> using FooServer = typename FooAssociations<T>::Server; // 现在Func里的类型获取就简洁多了 template<typename T> void Func(void) { using HelperType = FooHelper<T>; using ClientType = FooClient<T>; using ServerType = FooServer<T>; // 原有逻辑 }
这些方法都能帮你把模板参数从4个缩减到1个,大大减少调用时的重复代码,也让代码更易维护——以后如果FooX的关联类型变了,只需要修改一处关联定义就行,不用挨个改调用点。
内容的提问来源于stack exchange,提问作者Mihai
相关产品推荐
相关产品推荐

