Using `std::copy()` with `std::back_inserter()`

天涯浪子 提交于 2021-01-02 05:34:49

问题


I have two class A and B both have a member like below:

class A {
  ...
  std::vector<std::vector<std::vector<size_t>>> grid;
}

class B {
  ...
  std::vector<std::vector<std::vector<size_t>>> grid;
}

I found when I use std::copy() to copy from A::grid to B::grid, it will fail. Here is what I do:

// Here is in B's constructor.
// I initialize B::grid with the same size of A::grid
grid = vector<vector<vector<size_t>>>(GetSetting().grid_cols());
for (int i = 0; i < GetSetting().grid_cols(); i++) {
  grid[i] = vector<vector<size_t>>(GetSetting().grid_rows());
  for (int j = 0; j < GetSetting().grid_rows(); j++) {
    grid[i][j].reserve(a.grid[i][j].size());
  }
}

// Copy from A to B
std::copy(a.grid.begin(), a.grid.end(), std::back_inserter(grid));

But if I remove initialize part, then the std::copy will work fine. What's wrong for the initialize part?


回答1:


Let me show you with a simplified example.

std::vector<int> v = {1, 2, 3};
std::vector<int> v1;
std::copy(v.begin(), v.end(), std::back_inserter(v1));

In this scenario v1 will be 1, 2, 3, as expected. Now consider this:

std::vector<int> v = {1, 2, 3};
std::vector<int> v1(3); //v1 has initial size!!
std::copy(v.begin(), v.end(), std::back_inserter(v1));

Now v1 will be 0, 0, 0, 1, 2, 3, because back_inserter push_backs. If you have already allocated the necessary size in the destination, then use the begin() iterator and not the back_insert_iterator:

std::vector<int> v = {1, 2, 3};
std::vector<int> v1(3); //v1 has initial size!!
std::copy(v.begin(), v.end(), v1.begin()); //use begin here

v1 is 1, 2, 3, as expected.



来源:https://stackoverflow.com/questions/41997285/using-stdcopy-with-stdback-inserter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!