如何转换vector <vector <int>&gt;数组C ++

时间:2016-08-17 14:45:27

标签: c++ arrays vector int

我想知道是否有更智能的方法将std::vector<std::vector<int>转换为数组,因为每个矢量项具有固定大小:

我目前正在使用:

  unsigned int cell_size = pCells[0].size();
  std::vector<int> kCells(pCells.size()*cell_size);
  for (unsigned int i=0; i<pCells.size(); i++){
     for (unsigned int j=0; j< cell_size; j++){
    kCells[i*cell_size+j] = pCells[i][j];
     }
  }
  // array
  int* lCells = &kCells[0];

2 个答案:

答案 0 :(得分:1)

从2d向量获取int*的便捷方法是使用临时向量来构建缓冲区,然后指向该缓冲区。这种方法的下降是你必须确保指针不会超过向量,并且不会以导致指针变为无效的方式修改向量(通常这会导致重新分配或转移元素)。如果您对此没问题,那么您可以使用

std::vector<std::vector<int>> data; // we assume this is populated
std::vector<int> builder;
builder.reserve(data.size() * data[0].size()); // reserve space in builder. not needed but useful if you already now how many elements you need

for (const auto& row : data)
    builder.insert(builder.end(), row.begin(), row.end()

int * non_owning_ptr = &builder[0];

现在你有了一个非拥有指针,指向构建器的内容以及随附的所有陷阱。只要non_owning_ptr没有留下声明builder的范围,就可以避免陷阱,除非由于修改向量而可能失效。您可以将它传递给同一范围内的函数但你无法将其传递出当前范围。

另一种选择是使用std::unique_ptr<int[]>但您需要知道您需要多少元素,因为您无法增长unique_ptr。这比使用原始指针和new更好,因为您不需要记得在完成后调用delete。您仍然需要确保指针不会比std::unique_ptr更长的范围问题。您还必须确保不对其执行任何删除指针的操作,如调用reset。使用unique_ptr您可以使用

std::vector<std::vector<int>> data; // we assume this is populated
auto builder = std::make_unique<int[]>(data.size() * data[0].size());
int * end = builder.get(); // for std::copy

for(const auto& row : data)
{
    std::copy(row.begin(), row.end(), end);
    end += row.size();
}

int * non_owning_ptr = builder.get();

获取数组的唯一方法是new向上指针,将数据复制到新缓冲区,然后在完成后delete。这仍然不是最大的,因为你必须记得在完成缓冲后调用delete但至少指针&#34;拥有&#34;数据,可以在任何地方传递。您还必须确保您调用的任何内容都不会在指针上调用delete,否则当您删除它时将会有双重删除。

std::vector<std::vector<int>> data; // we assume this is populated
int * buffer = new int[data.size() * data[0].size()];
int * end = buffer; // for std::copy

for(const auto& row : data)
{
    std::copy(row.begin(), row.end(), end);
    end += row.size();
}

// use buffer here

// don't forget this when done
delete [] buffer;

答案 1 :(得分:-1)

C ++提供了许多比你正在做的更好的选择,从最佳到最差列出:

  1. 将您的vector<vector<int>>构建为vector<int>,在必要时将二维索引编入一维数组,然后甚至不必费心进行转换并直接使用vector<int>
  2. 使用#define来确定数组高度和宽度的大小,并使用array而不是vector来存储元素
  3. 最糟糕的情况就是你所做的事情,你做的事情更加残酷:int* lCells = &kCells[0]意味着lCells因任何使{{1}的迭代器无效的改变而失效}
  4. 1 要求您在问题代码外部进行更改,因此我不会证明这一点。 2 可以这样做,但是:kCells#define WIDTH 3,并且您的输入定义如下:#define HEIGHT 2您可以这样做:

    array<WIDTH, array<HEIGHT, int>> pCells

    Live Example