首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么std::copy()需要std::back_inserter插入到具有足够容量的向量中?

为什么std::copy()需要std::back_inserter插入到具有足够容量的向量中?
EN

Stack Overflow用户
提问于 2020-10-30 16:13:51
回答 2查看 292关注 0票数 1

参考代码:

代码语言:javascript
运行
复制
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>

void print(std::string label, std::vector<int> & arr) {
  std::cout << label << ":" << " size: " << arr.size() << " cap: " << arr.capacity() << " [ ";
  for (auto elem : arr) {
    std::cout << elem << " ";
  }
  std::cout << " ] " << std::endl;
}

void reserve_dest_use_begin() {
  std::vector<int> s_arr = {0, 1, 2, 3, 4, 5}; 
  print("source", s_arr);

  std::vector<int> d_arr;
  d_arr.reserve(3);
  print("dest", d_arr);

  auto min_elems = std::min(s_arr.size(), d_arr.capacity());

  std::cout << "COPYING FIRST" << min_elems << "3 FROM SOURCE TO DEST" << std::endl;

  std::copy(s_arr.begin(), s_arr.begin() + min_elems, d_arr.begin());

  print("source", s_arr);
  print("dest", d_arr);
}

void reserve_dest_use_back_inserter() {
  std::vector<int> s_arr = {0, 1, 2, 3, 4, 5}; 
  print("source", s_arr);

  std::vector<int> d_arr;
  d_arr.reserve(3);
  print("dest", d_arr);

  auto min_elems = std::min(s_arr.size(), d_arr.capacity());

  std::cout << "COPYING FIRST" << min_elems << " ELEMENTS FROM SOURCE TO DEST" << std::endl;

  std::copy(s_arr.begin(), s_arr.begin() + min_elems, std::back_inserter(d_arr));

  print("source", s_arr);
  print("dest", d_arr);
}

int main() {
  std::cout << "RESERVE DEST ARR. USE BEGIN() TO COPY" << std::endl;
  reserve_dest_use_begin();
  std::cout << "RESERVE DEST ARR. USE BACK_INSERTER() TO COPY" << std::endl;
  reserve_dest_use_back_inserter();

输出:

代码语言:javascript
运行
复制
RESERVE DEST ARR USE BEGIN() TO COPY
source: size: 6 cap: 6 [ 0 1 2 3 4 5  ] 
dest: size: 0 cap: 3 [  ] 
COPYING FIRST 3 ELEMENTS FROM SOURCE TO DEST
source: size: 6 cap: 6 [ 0 1 2 3 4 5  ] 
dest: size: 0 cap: 3 [  ] 
=============================================
RESERVE DEST ARR USE BACK_INSERTER() TO COPY
source: size: 6 cap: 6 [ 0 1 2 3 4 5  ] 
dest: size: 0 cap: 3 [  ] 
COPYING FIRST 3 ELEMENTS FROM SOURCE TO DEST
source: size: 6 cap: 6 [ 0 1 2 3 4 5  ] 
dest: size: 3 cap: 3 [ 0 1 2  ]

在这两种情况下,目标数组都有足够的容量。来自优先选择的文档表明:

代码语言:javascript
运行
复制
Copies the elements in the range, defined by [first, last), to another range beginning at d_first.
1) Copies all elements in the range [first, last) starting from first and proceeding to last - 1. The behavior is undefined if d_first is within the range [first, last). In this case, std::copy_backward may be used instead.

d_arr.begin()指向[first, last)源范围之外的范围,但在提供的示例中,我需要使用std::back_inserter()进行复制,而不是仅仅提供d_arr.begin(),尽管底层向量具有足够的容量。

std::back_inserter()操作是优化为只移动内存块,还是推回每个元素?国家优惠委员会的说明表明:

代码语言:javascript
运行
复制
In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy LegacyContiguousIterator.

但是,对于std::back_inserter(),我怀疑它没有使用memmove进行优化。

总括而言,我有以下问题:

  1. 当底层向量有足够的容量时,为什么不能使用d_arr.begin()作为OutputItstd::copy中呢?
  2. 是否对std::back_inserter()进行了优化以批量复制范围?

编辑:,我想我是从错误的角度回答这个问题的。评论中已经澄清,我想做的操作是insert(),而不是copy()。我的具体用例是,我反复clear()我的d_arr,并将一个子载体从s_arr复制到d_arr中。我正在努力避免重新分配我的d_arr。但是,由于d_arr是被清除的,而且虽然它有足够的容量,但是它没有大小,这意味着没有可以复制的元素。相反,我实际上想要做的是将s_arr的一个子向量插入到d_arr中。

代码语言:javascript
运行
复制
d_arr.insert(d_arr.begin(), s_arr.begin(), s_arr.begin() + min_elems)
EN

Stack Overflow用户

回答已采纳

发布于 2020-10-30 16:25:43

为什么当底层向量有足够的容量时,我不能使用d_arr.begin()作为std::OutputIt中的OutputIt?

因为目标向量是空的,因此std::copy溢出了向量(因为任何元素的赋值都超出了空向量的界限)。

是否对std::back_inserter()操作进行了优化,使之仅限于memmove

可能会吧。它甚至可能被优化为更快的东西。

是否对std::back_inserter()进行了优化以批量复制范围?

如果有足够聪明的乐天派,是的。

使用适当的向量构造函数将比std::copy更简单。对于代码的读者和优化器都是如此。

票数 3
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64612034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档