实现带非默认构造函数的类型键值可变参数模板映射
实现基于类型键的实例映射结构
问题描述
需要实现一个以类型为键的映射结构TypeToValMap,将指定类型的对象关联到对应Processor实例,支持通过类型直接获取实例并调用方法。预期使用方式如下:
// 前置定义 struct A; struct B; template<class T> struct Processor { Processor(T foo); void SomeFunction(); }; // 预期用法 int main(){ A a; B b; TypeToValMap<KeyValue<A, Processor<A>>, KeyValue<B, Processor<B>>> myMap{{a}, {b}}; // 用a、b构造对应Processor myMap.get<A>().SomeFunction(); // 获取Processor<A>实例并调用方法 myMap.get<B>().SomeFunction(); // 获取Processor<B>实例并调用方法 }
尝试使用std::variant或std::any存储实例未成功,询问是否可实现该结构。
实现方案
完全可以实现该结构,核心是利用编译期模板元编程绑定类型与实例,无需依赖std::variant或std::any,直接将每个KeyValue实例作为TypeToValMap的成员存储,通过编译期查找定位对应类型的成员。
完整实现代码
#include <utility> #include <type_traits> // 补全前置定义的结构体 struct A {}; struct B {}; template<class T> struct Processor { // 实现构造函数:接收T类型对象初始化 Processor(T foo) {} // 实现成员方法 void SomeFunction() {} }; // KeyValue:绑定键类型与值类型的结构体 template<class Key, class Value> struct KeyValue{ using key_type = Key; using value_type = Value; value_type val; // 转发构造函数:接收初始化Value的参数 template<typename... CtorArgs> explicit KeyValue(CtorArgs&&... args) : val(std::forward<CtorArgs>(args)...) {} }; // TypeToValMap核心实现:基于类型的实例映射 template<typename... KeyVals> struct TypeToValMap : private KeyVals... { // 构造函数:转发参数到每个KeyValue成员 template<typename... Args> explicit TypeToValMap(Args&&... args) : KeyVals(std::forward<Args>(args))... {} // 通过键类型T获取对应Value实例 template<class T> constexpr auto& get() { // 编译期找到对应Key为T的KeyValue成员 using TargetKV = KeyValue<T, typename GetValueByKey<T, KeyVals...>::type>; return static_cast<TargetKV&>(*this).val; } private: // 元函数:编译期通过键类型查找对应Value类型 template<class TargetKey, class KeyVal, class... Rest> struct GetValueByKey { using type = typename std::conditional_t< std::is_same_v<TargetKey, typename KeyVal::key_type>, typename KeyVal::value_type, typename GetValueByKey<TargetKey, Rest...>::type >; }; // 递归终止条件:未找到对应键时触发编译错误 template<class TargetKey> struct GetValueByKey<TargetKey> { static_assert(!std::is_same_v<TargetKey, TargetKey>, "Error: Target type not found in TypeToValMap"); }; };
关键说明
KeyValue结构:
- 绑定键类型
key_type与值类型value_type,存储值实例val - 提供转发构造函数,支持传递任意参数初始化
value_type(比如示例中的A/B对象)
- 绑定键类型
TypeToValMap结构:
- 私有继承所有
KeyValue模板参数,使每个KeyValue成为类的成员,避免命名冲突 - 构造函数通过参数转发,将每个初始化参数传递给对应
KeyValue的构造函数 get<T>()方法:- 利用
GetValueByKey元函数在编译期定位对应T的KeyValue类型 - 通过
static_cast转换到目标KeyValue成员,返回其内部的val实例 - 若传入未注册的类型键,编译期会触发断言报错,确保类型安全
- 利用
- 私有继承所有
性能与安全性:
- 所有类型匹配和实例查找都在编译期完成,无运行时开销
- 强类型检查,避免运行时类型转换错误
内容的提问来源于stack exchange,提问作者kekpirat
相关产品推荐
相关产品推荐

