使用 `std::copy()` 和 `std::back_inserter()`

Posted

技术标签:

【中文标题】使用 `std::copy()` 和 `std::back_inserter()`【英文标题】:Using `std::copy()` with `std::back_inserter()` 【发布时间】:2017-02-02 08:21:08 【问题描述】:

我有两个 A 类和 B 类都有如下成员:

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


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

我发现当我使用std::copy()A::grid复制到B::grid时,会失败。 这是我的工作:

// 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));

但是如果我删除初始化部分,那么 std::copy 会正常工作。 初始化部分有什么问题?

【问题讨论】:

你到底为什么不干脆grid = a.grid; @T.C. ,我也尝试使用 operator=() 并且它工作正常。我只是想知道我使用 std::copy 时出了什么问题 :) 【参考方案1】:

让我用一个简化的例子来告诉你。

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

在这种情况下,v1 将是 1、2、3,正如预期的那样。现在考虑一下:

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));

现在 v1 将是 0、0、0、1、2、3,因为back_inserterpush_backs。如果您已经在目标中分配了必要的大小,则使用 begin() 迭代器而不是 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 是 1、2、3。

【讨论】:

感谢您的回答,这让我很困惑。我可以再问一个问题吗?当我修改 grid[i][j].reserve(a.grid[i][j].size());到 grid[i][j].resize(a.grid[i][j].size());并使用 back_inserter,它也可以正常工作。保留和调整大小有什么区别?我知道储备器只是保留一个缓冲区,调整大小将初始化该值。但是为什么调整大小会正常工作? @Josper:我认为您对 grid[i][j] 所做的任何事情都不会产生影响,无论是调整储备大小。重要的是您是否调整网格本身的大小 其中哪一种效率更高? @nog642:使用 back_inserter 的可能会遭受多次重新分配 @ArmenTsirunyan 使用 back_inserter 方法并预先调用 reserve() 怎么样?这与初始大小方法本质上是否相同,还是有理由更喜欢其中一个?

以上是关于使用 `std::copy()` 和 `std::back_inserter()`的主要内容,如果未能解决你的问题,请参考以下文章

使用 std::copy 时出错

为啥在 std::copy 期间使用 std::back_inserter 而不是 end()?

C++、std::copy 和模板

在结构数组上使用 c++ std::copy

是否实现了 std::copy 以使用多个线程?

如何将 unique_ptr 与 std::copy 一起使用?