C++ unordered_map存多类型模板DataParam的shared_ptr报未特化错误如何解决
问题核心原因
C++中每个template <typename T> DataParam都是独立的、互不相干的类型,不存在可以直接兼容所有特化版本的DataParam类型,所以无法直接作为unordered_map的值类型存储不同数据类型的实例。
解决思路:类型擦除
通过给模板类DataParam<T>添加一个非模板的公共基类,让所有特化的DataParam<T>都继承这个基类,再让unordered_map存储基类的智能指针,就可以实现异构存储的需求。
关键修改点说明
- 新增公共基类
IDataParam
必须定义虚析构函数,否则通过基类指针释放子类对象时会出现内存泄漏
class IDataParam { public: virtual ~IDataParam() = default; };
- 修改
DataParam<T>继承自IDataParam
所有不同类型的DataParam实例都可以向上转型为IDataParam指针存入map。 - 修改
unordered_map的值类型为基类智能指针
unordered_map<string, shared_ptr<IDataParam>> params;
- 修正
AddParam的模板参数传递
实例化DataParam时必须明确传入模板参数T:
params.insert({ tag, make_shared<DataParam<T>>(tag, value) });
GetParam添加向下转型逻辑
读取参数时通过dynamic_cast将基类指针转型为对应类型的DataParam<T>指针再读取值。可以优化为指针转型的方式避免类型不匹配时抛出异常:
template <typename T> T GetParam(string tag, T def_value) { if (!HasParam(tag)) return def_value; auto ptr = dynamic_pointer_cast<DataParam<T>>(params.find(tag)->second); return ptr ? ptr->Value() : def_value; }
内容的提问来源于stack exchange,提问作者r0neko
相关产品推荐
相关产品推荐

