【问题标题】:copy algorithm vs. container constructor复制算法与容器构造函数
【发布时间】:2014-01-26 21:21:57
【问题描述】:

复制算法比直接使用容器的构造函数有什么优势?

这个例子来自cplusplus.com:

// copy algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy
#include <vector>       // std::vector

int main () {
  int myints[]={10,20,30,40,50,60,70};
  std::vector<int> myvector (7);

  std::copy ( myints, myints+7, myvector.begin() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

为什么要首选复制方法

std::vector<int> myvector(myints, myints+7);

【问题讨论】:

  • 一个版本比另一个版本做的事情更多。
  • 您从 cplusplus.com 获得的代码并不是您在实践中使用 std::copy 的一个很好的例子。

标签: c++ c++11 stl copy stdvector


【解决方案1】:

这是 cplusplus.com 上的一个糟糕示例。如果你有这样一个数组并且真的要将它复制到一个向量中,你会使用构造函数。 std::copy 在许多其他方面都很有用(例如,如果您想将数组输出到文件或控制台),但构造不是其中之一。

【讨论】:

    【解决方案2】:

    好吧,首先,既然您使用的是 C++11:

    int myints[]={10,20,30,40,50,60,70};
    std::vector<int> myvector(myints, myints+7);
    
    for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    

    实际上可以这样写:

    std::vector<int> myVector = {10,20,30,40,50,60,70};
    
    for (const int i : myVector )
        std::cout << ' ' << i;
    
    其次,您正在比较:
    • 使用迭代器直接构造向量与
    • 向量的构造,其中的元素将被std::copy覆盖。
    如果你想使用 C 风格的数组/迭代器构造一个向量,那么:
    std::vector<int> myVector(myints, myints+7);
    
    如果您想使用现有的向量构建另一个向量,则使用以下方法之一:
    std::vector<int> myVector2(myVector);
    std::vector<int> myVector3 = myVector;  // invokes copy constructor anyway...
    
    如果你已经有 2 个向量并且你想用另一个覆盖一个,那么:
    myVector2 = myVector;
    

    ...只是不要过早优化,让您的代码反映您的目的。

    【讨论】:

      【解决方案3】:

      这对构建新容器没有用处,因为大多数时候容器本身可以带迭代器

      如果您使用的是原始数组,则可能必须使用它。例如:

      std::vector<int> my_vect;
      int* array_for_a_low_level_lib = new int[my_vect.size()];
      std::copy(std::begin(my_vect), std::end(my_vect), array_for_a_low_level_lib);
      

      以下是我最喜欢的两个用法示例,添加iterator 标头:

      template <typename InnerType, typename Container>
      void fill_container(Container& cont)
      {
        std::copy(std::istream_iterator<InnerType>(std::cin), 
                  std::istream_iterator<InnerType>(), 
                  std::inserter(cont, cont.end()));
      }
      
      template <typename InnerType, typename Container>
      void print_container(const Container& cont)
      {
        std::copy(std::begin(cont), std::end(cont), 
          std::ostream_iterator<InnerType>(std::cout, " "));
      }
      

      http://ideone.com/4MOhSE

      还可以与boost::range 适配器一起使用,您可以做一些漂亮的事情,比如将地图中的矢量填充到一个可读性很强的行中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-21
        • 1970-01-01
        • 2013-09-28
        • 1970-01-01
        • 2010-09-11
        • 2013-03-16
        • 2013-10-13
        相关资源
        最近更新 更多