C++如何构造存储类型与对应名称的vector批量创建类对象
解答
首先你给出的Type结构写法没法实现需求,核心问题出在C++的基础类型规则上:
- 非静态数据成员不能是未绑定具体类型的模板成员,你写的
template<typename T> T t;本身就是非法语法,类的每个非静态成员的类型必须在类定义阶段就确定。 std::vector是同质容器,要求里面存的所有元素类型完全一致,你想让同一个Type结构一会儿存A的实例、一会儿存B的实例,本身就违反了这个要求。
这个需求是完全可以实现的,而且不需要修改外部框架提供的A和B的定义,最贴合你设计思路的是类型擦除+工厂的实现方式:
可运行的实现方案(C++17及以上,无侵入)
用可调用对象包装不同类型的构造逻辑,统一存在Type结构里,创建对象的时候按名称存到对象表中即可:
#include <vector> #include <string> #include <functional> #include <any> #include <unordered_map> // 以下是外部框架提供的类,不需要做任何修改 struct A { int i; }; struct B { int i; double d; }; // 修正后的Type定义 struct Type { std::string name; // 用统一的可调用接口包装不同类型的构造逻辑,返回擦除类型的对象 std::function<std::any()> create_instance; }; // 适配原来的vector初始化逻辑 std::vector<Type> v{ {"ObjA1", [](){ return A{.i = 0}; }}, {"ObjB", [](){ return B{.i = 0, .d = 0.0}; }}, {"ObjA2", [](){ return A{.i = 1}; }} }; // 对象创建函数实现 void fun(std::vector<Type> vec) { std::unordered_map<std::string, std::any> obj_map; for (auto& entry : vec) { obj_map[entry.name] = entry.create_instance(); } // 使用示例:按名称取出对应对象 A a1 = std::any_cast<A>(obj_map["ObjA1"]); B b = std::any_cast<B>(obj_map["ObjB"]); A a2 = std::any_cast<A>(obj_map["ObjA2"]); }
如果你的编译环境不支持C++17,把std::any和std::function换成自己实现的类型擦除基类即可,核心逻辑不变:把不同类型的构造逻辑包装成统一接口,绕开同质容器的类型限制。
如果你的类型列表在编译期就能完全确定,不需要运行时动态增减传入的类型,也可以用std::tuple做异构容器,没有运行时开销,但灵活性不如上面的类型擦除方案,没法处理运行时才确定的元素列表。
内容的提问来源于stack exchange,提问作者virus00x
相关产品推荐
相关产品推荐

