首页 > 解决方案 > 如何使用可变参数模板定义不同类型向量的向量?

问题描述

我想制作一个不同类型向量的向量。假设我有 4 节课;狗,猫,猪,牛。我想要一个包含每个向量的向量,并且能够通过两个索引访问它们,这样我就可以迭代它们,如果它是向量的向量,情况就是这样。

我一直在玩弄类似的东西:

std::vector<std::variant<std::vector<Dog>,
    std::vector<Cat>,
    std::vector<Pig>,
    std::vector<Cow>>>;

此外,我希望能够使用可变参数模板构造来构造这些数组,这样我就可以轻松地制作另一个向量,例如 Apple、Pear、Orange、Lemon、Grape、Cherry。

我希望能够在我的代码中编写如下内容:

MyVectorOfVectors<Dog,Cat,Pig,Cow> animals;
MyVectorOfVectors<Apple, Pear, Orange, Lemon, Grape, Cherry> fruits;

并为每种类型制作向量并将这些向量存储在我可以通过索引访问的另一个向量(或类似向量)中。显然,这个向量需要是某种异构容器,如上面所建议的,带有变体向量。我想这必须包含在某种可变参数模板类定义中。

所以访问数组中的第三个 Dog 需要一个类似这样的功能

Dog mydog = animals[0][3];

或者如果解决方案必须包含在一个类中,

Dog mydog = animals.thearray[0][3];

我意识到这可以使用类层次结构、动态分配和指向对象的指针来实现,但我正在寻找一种具有平面内存模型的解决方案以提高性能。

标签: c++templatesvectorc++17

解决方案


template<typename... T>
using MyVectorOfVectors = std::tuple<std::vector<T>...>;

MyVectorOfVectors<Dog,Cat,Pig,Cow> animals;
MyVectorOfVectors<Apple, Pear, Orange, Lemon, Grape, Cherry> fruits;

void foo()
{
    std::vector<Dog>& dogs = std::get<0>(animals);
    std::vector<Orange>& oranges = std::get<2>(fruits);
}

演示

您必须决定:您可以在编译时推断类型(在这种情况下,您的索引MyVectorOfVectors也必须在编译时知道) - 然后您获得所有类型安全(如上所述)。

如果您的索引也可以是运行时值,那么您需要一种类型擦除形式。这将伴随您说要避免的运行时开销。

在任何情况下,您都不会得到Dog dog = animals[0][3],因为最终结果的参数不一定在编译时已知(至少从编译器的角度来看)。operator[]MyVectorOfVectors


推荐阅读