【问题标题】:Add element in single/multiple lists in a vector of list在列表向量中的单个/多个列表中添加元素
【发布时间】:2016-07-17 23:47:58
【问题描述】:

我已经声明了一个列表和 3 个列表的向量,并将这 3 个列表添加到向量中。现在我想通过使用仅矢量将一些元素添加到这 3 个列表中的 2 个。我怎样才能做到这一点?
到目前为止,这是我的代码:

#include<iostream>
#include<list>
#include<vector>
using namespace std;


#ifndef ILIST
#define ILIST list<int>
#endif

#ifndef VLIST
#define VLIST vector<ILIST >
#endif

int main(int argc, char const *argv[])
{
    ILIST l1(4,10), l2(4,20), l3(4,30);
    VLIST vec;
    vec.push_back(l1);
    vec.push_back(l2);
    vec.push_back(l3);
    //here I want to add 2 elements in l2 and 1 in l3 by using the vector only. 
    return 0;
}

【问题讨论】:

  • 为什么要写 3 行代码来定义类型别名而不是 using ILIST = std::list&lt;int&gt;;
  • 另外,vec.push_back(x)vec 的后面创建x 的新副本,因此您必须将vec 存储的内容更改为指针或std::reference_wrapper .
  • @kfsone 我不知道第一种方法,我还不熟悉 C/CPP 的所有概念。最近由于 Java 性能不佳而搬到这里。我想你的第二条评论是我的答案,对吧?
  • 最好稍微澄清一下为什么要同时拥有列表的两个视图 - 答案的实现需要更多地跳到 C++ 稍深的一端(指针可能是一个主要的学习C++的痛点,而reference_wrapping是C++11,新语言,新特性)
  • @kfsone 我想根据动态提供的玩家数量将 52 张卡分成一组相等的玩家。所以向量将保存我可以遍历的每个玩家的卡片列表。

标签: c++ list vector stl


【解决方案1】:

快速了解当前代码的作用:

ILIST l1(4,10), l2(4,20), l3(4,30);

三个局部变量。

VLIST vec;

一个局部向量。

vec.push_back(l1);

向量现在分配一些动态内存来存储至少一个 ILIST,然后将 l1 的内容复制到该内存中。两者现在是独立的。

如果你想要一个本质上是一个视图的向量,允许你通过它来操作目标对象,你需要在你的向量中存储一个指针或引用:

#include <iostream>
#include <list>
#include <vector>

using ilist_t = std::list<int>;
using vecilist_t = std::vector<ilist_t*>;

int main()
{
    ilist_t il;  // empty list
    vecilist_t vec;  // empty vector

    vec.push_back(&il);  // store address in vec[0]

    vec[0]->push_back(42);  // vec[0] has type `ilist_t*`, -> dereferences

    for (int i : il) {
        std::cout << i << '\n';
    }
}

正如你已经表明你是一个学习者,我会指出,使用像这样的原始指针,你可以确保指向的对象持续的时间比通过向量的潜在使用时间长:

vecilist_t f() {
    ilist_t i;
    vecilist_t v;
    v.push_back(&i);
    return v;
}

int main() {
    auto v = f();
    v[0]->push_back(42);  // undefined behavior, probably crash
}

f 返回的向量的地址为i,它具有自动存储持续时间 - 它的生命周期在函数范围的末尾结束,这使得我们返回的对象中指向它的指针无效,并且会出现未定义的行为。

--- 编辑 ---

不清楚为什么需要独立列表。如果您想要的只是 3 个列表的向量,您可以执行以下操作:

#include <vector>
#include <list>

using ilist_t = std::list<int>;
using ilvec_t = std::vector<ilist_t>;

int main() {
    ilvec_t ilvec;
    ilvec.resize(3);  // now contains 3 empty lists.

    // push a value onto the 2nd list
    ilvec[1].push_back(42);
}

如果你的向量将有一个编译时固定大小,你可以使用 std::array 来代替。

using ilarray_t = std::array<ilist_t, 5>;  // compile time size fixed at 5.

【讨论】:

  • for (int i : il) { std::cout &lt;&lt; i &lt;&lt; '\n'; } 我希望能够使用向量对象而不是列表本身来遍历列表的元素。
  • 没关系,我想通了。代码的第二部分,你能建议我解决这个问题吗?
  • @AkashAggarwal 我试图了解您是否需要独立列表,或者您是否只需要一个列表向量。要通过向量向l2 添加元素,请使用vec[1]-&gt;push_back(value);。代码的第二部分就是这个意思吗?
  • 代码的第二部分是第二个sn-p,如果我不清楚,对不起。我遇到了您指定的问题,因为我在 for 循环中创建 ilist 并将其地址推送到 vlist。由于列表在for 块之后被破坏,我遇到了分段错误。我认为对我来说最好的方法是使用ilist 的对象数组,并且动态生成对象的数量。
猜你喜欢
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 2021-03-21
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多