容器的可变参数模板对象创建功能无法正常工作
我来帮你排查下这段代码里的问题,几个小细节没处理好导致创建对象失败,咱们一步步来修正:
问题分析与修复方案
1. std::unordered_map 缺少模板参数
你定义的 m_objects 只写了 std::unordered_map,但这个容器必须明确键值对的类型才能正常工作。需要补充为:
std::unordered_map<size_t, Base*> m_objects;
这样才能正确存储 size_t 类型的ID,以及对应的基类指针。
2. 派生类的继承方式错误
你写的 class A : Base; 和 class B : Base; 默认是私有继承,这意味着从派生类到基类的类型转换在外部是不可访问的——create 函数里 new Type(args...) 生成的派生类指针,无法传给 add 函数的 Base* 参数。必须改成公有继承:
class A : public Base; class B : public Base;
3. create 函数的调用方式有误
你写的 container.create<B, Vect... 是错误的,create 模板的 Args 参数可以通过函数实参自动推导,不需要显式指定。正确的调用方式是:
// 假设B的构造函数需要Vect类型参数,直接传对应实参即可 container.create<B>(vect_instance); // 如果是多参数构造: container.create<B>(arg1, arg2, arg3);
修正后的完整代码片段
#include <unordered_map> #include <utility> // 用于std::forward // 先声明Base类 class Base {}; class Container { private: size_t m_next_id = 0; // 初始化默认值,避免未定义行为 std::unordered_map<size_t, Base*> m_objects; public: template<typename Type, typename... Args> size_t create(Args&&... args) { // 用std::forward做完美转发,适配左值/右值参数 return this->add(new Type(std::forward<Args>(args)...)); } size_t add(Base* obj) { m_objects.emplace(m_next_id, obj); return m_next_id++; } }; // 派生类改为公有继承 class A : public Base {}; class B : public Base { public: // 示例带参数的构造函数 B(int num, const std::string& str) {} }; // 调用示例 int main() { Container container; auto a_id = container.create<A>(); auto b_id = container.create<B>(123, "hello"); return 0; }
额外提示:加上 std::forward<Args>(args)... 可以实现参数的完美转发,避免不必要的拷贝,让 create 函数适配更多场景。
内容的提问来源于stack exchange,提问作者Glen Fletcher
相关产品推荐
相关产品推荐

