【问题标题】:Copying/inserting a Vector复制/插入矢量
【发布时间】:2012-08-31 16:25:16
【问题描述】:

我正在阅读 Accelerated C++,对于下面发布的问题,我需要一些建议。

  1. 这段代码有什么作用?

    vector<int>u(10,100)    
    vector<int>v;    
    copy(u.begin(), u.end(), v.end());
    
  2. 提供 2 种可能的方法来纠正程序,并列出其优缺点。

第一部分非常简单,但我在第二部分需要帮助。我提供了 3 种方法,我想知道是否还有其他可能的解决方案。

另外,我不确定我的方法的优缺点。我已经尝试过了,请给我你的意见。


copy()

std::vector<int> u(10, 100);
std::vector<int> v;
std::vector<int> w ;
std::vector<int> x ;
std::copy(u.begin(), u.end(), back_inserter(v)); // 1st way of doing

优势

  • std::copy() 不会改变迭代器的值
  • 由于std::copy()的参数不依赖于具体的容器,所以代码可以和不同的容器复用

缺点

  • std::back_inserter() 仅适用于顺序容器,因此不能与地图一起使用
  • 将错误的迭代器值分配给std::copy() 的第三个参数不会导致编译器错误,但程序的行为可能会有所不同

insert()

w.insert(w.end(), u.begin(), u.end() );

优势

  • insert() 可用于大多数容器

缺点

想不出来。


push_back()

for ( std::vector<int>::const_iterator it = w.begin(); it != w.end(); ++it )
{
    x.push_back( *it );
}

优势

想不出来。

缺点

  • std::copy()vector::insert() 慢。

我的方法正确吗?还有哪些其他可能的解决方案?

【问题讨论】:

  • 在所有情况下,您都忘记了dest.reserve(src.size()); :) 尽管dest.insert(...) 很可能会在内部通过src_end - src_begin 执行此操作,但最好提前执行,因为它不能保证(而且您反正手头有大小)。
  • @xeo,感谢您提供此信息。您如何看待我所遵循的方法的好坏?
  • @Xeo -- 除非使用专门的自定义分配器或重复分析的数据表明如此,否则我很少看到需要使用 reservecapacity
  • std::vector::assign,使用普通迭代器调整大小和复制
  • v=u 有什么问题?

标签: c++ vector insert copy


【解决方案1】:

您的标题表明您对复制向量感兴趣,但您的代码表明您对插入向量感兴趣(请记住,尽管它的名称 std::copy 用于此处插入)。

如果你想复制:

// This requires the vector types to match exactly
std::vector<int> v = u;

// In case the vector differ in their value_type
// This requires that the value_type of the source be
// convertible to the value_type of the destination
std::vector<int> v(u.begin(), u.end());

如果您想插入,那么您描述的两种方法(使用std::copy 加上一个迭代器适配器或调用insert 成员)都是合适的。您应该根据您在特定代码位置中是使用容器还是使用迭代器来选择一个。 (使用迭代器时,使用迭代器适配器的负担由传递迭代器的客户端承担,因此无需担心push_back。)如果您只有迭代器,则调用例如insert 根本不是一种选择;如果您确实有容器并且其中一名成员可以完成这项工作,那么请随意使用它。不过,我不会认为使用算法会出错。

尝试将显式循环作为最后的选择。

【讨论】:

  • 还有一个复制构造函数可以用来代替赋值运算符:std::vector&lt;int&gt; v(u);。这样uv 的构造过程中被复制,其中赋值运算符在v 被构造时复制u
  • @Helstein 不涉及赋值运算符。
【解决方案2】:

在我看来,作者的意思是仍然应该使用 std::copy()。所以第一个解决方案是(如你所建议的):

std::copy(u.begin(), u.end(), back_inserter(v));

另一个可能是:

v.resize(u.size());
std::copy( u.begin(), u.end(), v.begin() );

【讨论】:

    猜你喜欢
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多