简体   繁体   English

如何创建包含三种不同类型向量的向量

[英]How can I create a vector that holds three different types of vectors

I have three structs (Foo, Bar, Fruit) and I want a vector to hold each struct like vector<Foo> Foo_holder; vector<Bar> Bar_holder; vector<Fruit> Fruit holder; 我有三个结构(Foo,Bar,Fruit),我想要一个向量来保存每个结构,例如vector<Foo> Foo_holder; vector<Bar> Bar_holder; vector<Fruit> Fruit holder; vector<Foo> Foo_holder; vector<Bar> Bar_holder; vector<Fruit> Fruit holder; and then I want to try and put all three of those vectors into one vector. 然后我想尝试将所有三个向量放到一个向量中。 So it should end up like this with Vector_holder being the top level vector that I wish to know how to create: 因此,它应该以Vector_holder作为我希望知道如何创建的顶级向量最终结束:

Vector_holder

--- Foo_Holder
------Instance of Foo

--- Bar_holder
------Instance of Bar

--- Fruit_holder
------Instance of Fruit

How do I go about doing this? 我该怎么做呢?

The possible duplicate question lists a problem that the vectors must be the same size or the code breaks, and the vectors in my question will be shifting size a whole lot. 可能出现的重复问题列出了一个问题,即向量的大小必须相同,否则代码会中断,而我的问题中的向量将在整个大小上变化。 I also feel this would help beginner C++ learners more than the other question. 我还认为,这比其他问题对初学者C ++学习者的帮助更大。 The solution I found here works for me and is overall alot simpler than the nearly essay long answer. 我在这里找到的解决方案对我有用,并且比几乎长篇论文的答案总体上更简单。 I'm more of a beginner in C++ and as such appreciate the easier to understand answer here. 我更多地是C ++的初学者,因此请欣赏此处更易于理解的答案。

Whenever such a grouping makes sense, I tend to put it into a struct and hence name it. 只要这样的分组有意义,我就倾向于将其放入struct并因此命名。 In this case, 在这种情况下,

struct FooBarFruitHolder {
    std::vector<Foo> foos;
    std::vector<Bar> bars;
    std::vector<Fruit> fruits;
};

which you can then use as 然后您可以将其用作

std::vector<FooBarFruitHolder> vec;

vec.emplace_back();

and eg fill it with objects: 并用对象填充它:

/* Add a Foo element to all FooBarFruitHolder instances. */
for (auto&& fooBarFruitHolder : vec)
    fooBarFruitHolder.foos.emplace_back(/* Arguments passed to Foo ctor */);

The naming is essential here, so choose what fits best in your application. 在这里命名是必不可少的,因此请选择最适合您的应用程序的名称。 Initialization might also be easier to read when you pass parts of this nested datastructure into functions which setup the member variables, eg 当您将此嵌套数据结构的某些部分传递给设置成员变量的函数时,初始化可能也更容易阅读

void initialize(std::vector<Foo>& foos)
{
    foos.emplace_back(/* Arguments for first Foo object */);
    foos.emplace_back(/* Arguments for second Foo object */);
}

initialize(vec.front().foos);

vector to hold each struct like vector Foo_holder; 像矢量Foo_holder一样保存每个结构的矢量; vector Bar_holder; 向量Bar_holder; vector Fruit holder; 向量水果架; and then I want to try and put all three of those vectors into one vector. 然后我想尝试将所有三个向量放到一个向量中。

One way to interpret your (somewhat ambiguous) statement is that you also want a single vector that holds all N element types in it. 解释您的(有点模棱两可的)语句的一种方法是,您还想要一个向量,其中包含所有N个元素类型。 (But I suspect you will like lubgr's answer better.) (但我怀疑您会更喜欢lubgr的答案。)

For this the third vector, I suggest you consider Polymorphism. 为此,我建议您考虑多态性。


If you derive each of your structs from an interface class, perhaps 如果您从接口类派生每个结构,也许

class FooBarFruit_t 
{
    //...
    virtual void whistle() = 0;
    virtual void bounce()  = 0;
    virtual void f1()      = 0;
    virtual void f2()      = 0;
    virtual void f3()      = 0;
    virtual void reflect();

    //...
}

then you can easily create a vector where any of the N types can be loaded 那么您可以轻松创建一个可以加载N个类型中的任何一个的向量

std::vector<FooBarFruit_t*> holder;  

The next challenge will be to create virtual methods that each derived class can support. 下一个挑战将是创建每个派生类都可以支持的虚拟方法。

a) They may be abstract, f1(), f2() ... a)它们可能是抽象的f1(),f2()...

b) They may be very specific, such as whistle(), which is something that only foo can do (and bars and fruit would take no action on being commanded to whistle()). b)它们可能非常具体,例如whistle(),这是只有foo才能做的事情(并且条和水果在被命令发出whistle()时不会采取任何措施)。

[I'm not sure what kind of behavior these typically in-animate instances might take, but software is where abstraction really helps.] [我不确定这些通常处于无生命状态的实例会采取什么样的行为,但是抽象确实可以帮助软件。


What this buys you is, at run time, you do not have to know what kind of FooBarFruit_t you are commanding to action. 这可以为您带来好处,在运行时,您不必知道要命令采取哪种FooBarFruit_t。

By invoking f3(), each instance (foo or bar or fruit) will do what what you ask, and each f3() simply fulfills the expectation you have for that type. 通过调用f3(),每个实例(foo,bar或fruit)将按照您的要求执行操作,并且每个f3()都完全满足您对该类型的期望。

If the instance does not reflect(), you can either implement a method that a) does nothing, or b) invokes FooBarFruit_t::reflect(). 如果该实例未反映(),则可以实现一个方法,该方法a)不执行任何操作,或者b)调用FooBarFruit_t :: reflect()。 Or several other options. 或其他几种选择。

Consider that you might want to display all objects: 考虑到您可能要显示所有对象:

 for (auto fbf : holder)  fbf->show();

 for (auto fbf : holder)  fbf->diagnostic();  // or diagnostic

 for (auto fbf : holder)  fbf->reset();       // or reset

Any reason these need to be considered different? 有什么理由需要将这些视为不同?


There should not be a place where you feel the need to do something specific based on type: 应该有,你觉得有必要基于类型做一些特定的地方:

 void something() {
 for (auto fbf : holder) {

    switch(fbf.type())
    { // vvvvv - enumeration of types
       case   Foo: foosomething(); break;
       case Fruit: fruitsomething(); break;
       case   Bar: barsomething(); break;
       default : assert(0); break;
    }
 }
 }

But no one will stop you from doing so you think you must. 但是没有人会阻止您这样做,因此您认为自己必须这样做。

You could use Boost's zip iterator to "zip together" the different vectors: 您可以使用Boost的zip迭代器将不同的向量“压缩在一起”:

vector<Foo> Foo_holder; 
vector<Bar> Bar_holder; 
vector<Fruit> Fruit holder; 

/* ... insert elements etc. */

auto start = boost::make_zip_iterator(
    std::make_tuple(ia.begin(), d.begin(), ib.begin())
    );
auto end = boost::make_zip_iterator(
    std::make_tuple(ia.end(), d.end(), ib.end())
    );

Now, this doesn't result in a vector, just a pair of iterators. 现在,这不会产生向量,而只是一对迭代器。 But now you can use them with STL algoritms. 但是现在您可以将它们与STL算法一起使用。 For example: 例如:

std::for_each(start, end, [](auto a_foo, auto a_bar, auto a_fruit) {
    std::cout << "The Foo   element is " << foo << "\n";
    std::cout << "The Bar   element is " << bar << "\n";
    std::cout << "The Fruit element is " << fruit << "\n";
}

and you can also use these iterators to create a single range object. 并且您还可以使用这些迭代器来创建单个范围对象。 This is described, for example, in this answer by @leemes to a related question of mine. 例如,@ leemes在此答案中对我的一个相关问题进行了描述。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何创建一个包含对象的向量? - How do I create a vector that holds objects? 在C ++中,当两个向量类型不同时,如何将值存储到向量内部的向量中? - In C++, How do I store values into a vector that is inside of a vector when the two vectors are of different types? 如何在 C++ 中创建一个包含不同类型函数指针的容器? - How to create a container that holds different types of function pointers in C++? 如何创建向量向量的笛卡尔积? - How can I create cartesian product of vector of vectors? 给定一个元组,其中任意数量的向量具有不同的类型,如何提取最小大小的向量? - Given a tuple with arbitrary number of vectors holding different types how do I extract the vector with minimum size? 如何使用可变参数模板定义不同类型的向量的向量? - How do I define a vector of vectors of different types using a variadic template? 是否可以创建一个容纳三种数据类型之一的容器,并且可以通过单个界面查询? - Is it possible to create a container that holds one of three data types, and can be queried through a single interface? 如何创建不同类型的多维矢量/数组? - How do I create a multidimensional vector/array of different types? 如何创建向量的向量? - How to create a vector of vectors? 创建包含两种不同数据类型或类的向量 - Creating a vector that holds two different data types or classes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM