将矢量引用复制到另一个

Posted

技术标签:

【中文标题】将矢量引用复制到另一个【英文标题】:Copying a vector reference to another 【发布时间】:2011-01-13 04:58:31 【问题描述】:

我有一个结构,比如 SubscriptionData。该类型的两个变量在函数 1 中声明。

SubscriptionData aSubscriptionData;
SubscriptionData aResultSubscriptionData;

结构本身具有另一个结构,而该结构又具有另一个结构的向量。向量在下面给出

aSubscriptionData.apn_config_file.apn_config

我已正确初始化结构。现在,我调用一个函数来填充 aSubscriptionData。然后我调用另一个函数,其原型如下所示。

void breakSubDataLen(ImsMsg::SubscriptionData& aSubscriptionData, ImsMsg::SubscriptionData& aResultSubscriptionData);

在函数breakSubDataLen()中,我应该将aSubscriptionData.begin()+3到aSubscriptionData.end()的元素复制到aResultSubscriptionData结构中。

我正在为此做以下操作。

std::copy(aSubscriptionData.apn_config_file.apn_config.begin() + 3, 
    aSubscriptionData.apn_config_file.apn_config.end(),
    aResultSubscriptionData.apn_config_file.apn_config.begin());

它似乎不起作用。谁能帮帮我?

【问题讨论】:

我很抱歉这里有错误的代码 sn-p。实际的行是 std::copy(aSubscriptionData.apn_config_file.apn_config.begin()+3, aSubscriptionData.apn_config_file.apn_config.end(), aResultSubscriptionData.apn_config_file.apn_config.begin()); 已为您修复。顺便说一句,apn_configstd::vector,对吧? “它似乎不起作用”是一个模糊的问题描述。 是的.. apn_config 是一个 std::vector。我正在尝试您的解决方案。 成功!! @James:非常感谢伙计! 【参考方案1】:

std::copy 不分配元素;您必须确保目标范围中有足够的空间来容纳源范围中的所有元素。

执行此操作的常用方法是使用std::back_inserter,它调用push_back 将每个元素插入容器:

std::copy(source.begin(), source.end(), std::back_inserter(destination));

另一种常见的方法是使用resize在目标序列中预先分配足够的空间:

destination.resize(std::distance(source.begin(), source.end()));
std::copy(source.begin(), source.end(), destination.begin());

当然,这两种方法具有不同的行为。使用std::back_inserter,将保留序列中的任何元素,并在现有元素之后插入新元素。使用resize 方法,任何现有元素都会被覆盖。您还可以使用resize 方法并保留任何现有元素:

const std::size_t original_size = destination.size();
destination.resize(destination.size() + 
                   std::distance(source.begin(), source.end());

std::copy(source.begin(), source.end(), destination.begin() + original_size);

(这要求destination 是像std::vector 这样的随机可访问容器;如果不是,则必须相应地修改代码。)

【讨论】:

resize 方法还会对输入进行两次迭代,如果迭代有副作用,例如从非搜索文件中消耗数据,这可能很重要。 @Mike:是的,确实如此;源迭代器需要是 ForwardIterator(因为 OP 有一个容器,所以几乎可以肯定源范围是可前向迭代的)。 vector 的范围插入函数不应该本质上做到这一点,并且更有效吗? @JaredC:是的,这绝对更干净(+1),但我不确定它是否会更有效。如果源是 InputIterator 范围,则该向量要么需要使用 back_inserter 方法,要么需要累积到辅助存储中,然后使用 resize 方法(我不是 100% 肯定这种方法会被严格允许)。如果源是 ForwardIterator 范围,则可以直接使用 resize 方法。 效率问题是一个有趣的问题,因为标准库实现者针对他们认为的“常见情况”进行了优化。我现在正在编写一个词法分析器生成器,它有一个转换迭代器,可以将字符序列转换为标记序列。实际的标记化过程相对昂贵,所以最好只做一次。使用 std::vector 的 Visual C++ 实现,如果我将 insert(...) 与我的 ForwardIterator 一起使用,它会执行两次标记化:一次调用 std::distance 以计算序列中的元素数,然后【参考方案2】:

通过将aResultSubscriptionData.apn_config_file.apn_config.begin() 作为第三个参数传递给std::copy,您是在告诉它您已经为它分配了足够的空间来分配.begin() 开始的元素。如果向量中有 0 个元素,那么很明显 .begin().begin() + X 没有引用有效的迭代器。如果向量已经包含足够的元素,或者如果它被调整大小,这将起作用,在这种情况下,它将元素复制到新的向量中。

您想使用的很有可能是使用vectors 范围插入。我相信它会更有效率:

aResultSubscriptionData.apn_config_file.apn_config.insert(0, aSubscriptionData.apn_config_file.apn_config.begin() + 3, aSubscriptionData.apn_config_file.apn_config.end());

【讨论】:

以上是关于将矢量引用复制到另一个的主要内容,如果未能解决你的问题,请参考以下文章

尝试在矢量类中创建复制功能

在javascript中将对象数组复制到另一个数组而没有对象引用(深拷贝)

将项目从一个向量复制到另一个向量

C ++创建一个矢量大小的数组,然后将矢量复制到C样式数组[复制]

js中的浅拷贝和深拷贝

如何将EXCEL中符合条件的数据利用公式复制到另一个工作表