如何在std::vector中存储不同模板参数的Element类实例?
解决方案
针对存储不同模板参数的Element实例的需求,可根据你的实际场景选择以下3种优化方案,均无需手动枚举所有N的取值:
方案1:基于非模板基类的多态实现
适合N取值范围不固定、后续需求变动大的场景,通过抽象基类统一不同模板实例的对外接口,vector存储基类智能指针即可:
#include <vector> #include <memory> // 无模板参数的公共抽象基类 class ElementBase { public: // 定义所有Element需要对外暴露的公共虚接口 virtual size_t get_array_len() const = 0; virtual int* get_array() = 0; virtual const int* get_array() const = 0; virtual ~ElementBase() = default; }; template <size_t N> class Element : public ElementBase { int array[N]; public: size_t get_array_len() const override { return N; } int* get_array() override { return array; } const int* get_array() const override { return array; } // 其余Element专属逻辑实现 }; int main(){ std::vector<std::unique_ptr<ElementBase>> vec; vec.emplace_back(std::make_unique<Element<1>>()); vec.emplace_back(std::make_unique<Element<8>>()); vec.emplace_back(std::make_unique<Element<20>>()); // 后续直接调用基类虚接口操作元素即可 }
方案2:编译期自动生成variant类型列表
适合N的最大取值在编译期固定、想要避免动态内存开销的场景,通过模板元编程自动生成std::variant的可选类型列表,仅需修改一次最大N值即可:
#include <vector> #include <variant> #include <utility> template <size_t N> class Element{ int array[N]; }; // 辅助模板:根据最大N值自动生成variant的类型列表 template <size_t MaxN, typename Seq = std::make_index_sequence<MaxN>> struct ElementVariantGen; template <size_t MaxN, size_t... Is> struct ElementVariantGen<MaxN, std::index_sequence<Is...>> { // N从1开始取值所以用Is+1,若从0开始直接用Is即可 using type = std::variant<Element<Is + 1>...>; }; // 仅需修改此处的最大N值即可适配需求,无需手动枚举所有类型 constexpr size_t MAX_SUPPORT_N = 30; using ElementVariant = typename ElementVariantGen<MAX_SUPPORT_N>::type; int main(){ std::vector<ElementVariant> vec; vec.emplace_back(Element<2>{}); vec.emplace_back(Element<15>{}); vec.emplace_back(Element<27>{}); // 正常使用std::visit操作variant元素即可 }
方案3:自定义类型擦除包装类
如果既不想承担虚函数的运行时开销,也不想限制N的最大取值,可以自行实现擦除N参数的Element包装类,通过小对象优化避免动态内存分配,适合对性能要求极高的场景。
内容的提问来源于stack exchange,提问作者LI.LE
相关产品推荐
相关产品推荐

