我有三个结构(Foo,Bar,Fruit),我想要一个向量来保存每个结构,如vector<Foo> Foo_holder; vector<Bar> Bar_holder; vector<Fruit> Fruit holder;
,然后我想尝试将所有这三个向量放入一个向量中。所以它应该像这样结束,Vector_holder
是我希望知道如何创建的顶级向量:
Vector_holder
--- Foo_Holder
------Instance of Foo
--- Bar_holder
------Instance of Bar
--- Fruit_holder
------Instance of Fruit
我该怎么做?
可能重复的问题列出了一个问题,即向量必须是相同的大小或代码中断,并且我的问题中的向量将大量移动大小。我也觉得这对初学者C ++学习者比其他问题更有帮助。 我在这里找到的解决方案对我有用,总体上比近篇文章的长答案简单得多。我更喜欢C ++的初学者,因此在这里更容易理解答案。
答案 0 :(得分:7)
每当这样的分组有意义时,我倾向于将其放入struct
并因此命名。在这种情况下,
struct FooBarFruitHolder {
std::vector<Foo> foos;
std::vector<Bar> bars;
std::vector<Fruit> fruits;
};
然后您可以将其用作
std::vector<FooBarFruitHolder> vec;
vec.emplace_back();
和用对象填充它:
/* Add a Foo element to all FooBarFruitHolder instances. */
for (auto&& fooBarFruitHolder : vec)
fooBarFruitHolder.foos.emplace_back(/* Arguments passed to Foo ctor */);
命名在这里至关重要,因此请选择适合您应用的最佳选择。将此嵌套数据结构的一部分传递给设置成员变量的函数时,初始化也可能更容易阅读,例如
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);
答案 1 :(得分:0)
vector用于保存每个结构,如vector Foo_holder;向量 Bar_holder;矢量水果架;然后我想尝试并把它 所有这三个向量都变成一个向量。
解释你的(有点模棱两可的)语句的一种方法是你还需要一个包含所有N个元素类型的向量。 (但我怀疑你会更喜欢lubgr的答案。)
对于第三个载体,我建议你考虑多态性。
如果从接口类派生每个结构,也许
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();
//...
}
然后您可以轻松创建一个向量,其中可以加载任何N种类型
std::vector<FooBarFruit_t*> holder;
下一个挑战是创建每个派生类都可以支持的虚方法。
a)它们可能是抽象的,f1(),f2()......
b)它们可能非常具体,例如whistle(),这是foo只能做的事情(酒吧和水果不会被命令吹口哨())。[我不确定这些典型的动画实例可能会采取什么样的行为,但软件是抽象真正有用的地方。]
这给你买的是,在运行时,你不必知道你指挥什么样的FooBarFruit_t。
通过调用f3(),每个实例(foo或bar或fruit)都会按照你的要求执行,每个f3()只是满足你对该类型的期望。
如果实例没有反射(),你可以实现a)什么都不做的方法,或者b)调用FooBarFruit_t :: reflect()。或其他几个选项。
考虑您可能想要显示所有对象:
for (auto fbf : holder) fbf->show();
for (auto fbf : holder) fbf->diagnostic(); // or diagnostic
for (auto fbf : holder) fbf->reset(); // or reset
任何理由都需要被视为不同?
不应该是您认为需要根据类型执行某些操作的地方:
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;
}
}
}
但没有人会阻止你这样做,你认为你必须这样做。
答案 2 :(得分:0)
您可以使用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())
);
现在,这不会产生向量,只会产生一对迭代器。但现在您可以将它们与STL算法一起使用。例如:
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";
}
您还可以使用这些迭代器来创建单个范围对象。例如,@ this answer通过@leemes对我的相关问题进行了描述。