使用 `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_inserter
push_back
s。如果您已经在目标中分配了必要的大小,则使用 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()`的主要内容,如果未能解决你的问题,请参考以下文章