C++ C++;:高效复制容器

C++ C++;:高效复制容器,c++,C++,如何复制STL容器 // big containers of POD container_type<pod_type> source; container_type<pod_type> destination // case 1 destination = source; // case 2 destination.assign(source.begin(), source.end()); // case 3 assumes that destination.siz

如何复制STL容器

// big containers of POD
container_type<pod_type> source;
container_type<pod_type> destination

// case 1
destination = source;

// case 2
destination.assign(source.begin(), source.end());

// case 3 assumes that destination.size() >= source.size()
copy(source.begin(), source.end(), destination.size());
//吊舱的大容器
容器型源;
集装箱类型目的地
//案例1
目的地=来源;
//案例2
destination.assign(source.begin(),source.end());
//案例3假设destination.size()>=source.size()
复制(source.begin()、source.end()、destination.size());
我尽可能使用案例1。案例2适用于不同类型的容器。当目标大于源并且希望保留其余元素时,需要案例3

但非POD元件的建造/破坏成本非零又如何呢?案例3能比案例2更好吗?如果目标大于源,那么实现可能会做一些意想不到的事情。这就是VisualStudio2008在案例2中所做的

  • 目的地的所有元素都将被销毁
  • 然后,复制构造函数的调用次数与目标大小相同。为什么?
  • 源的所有元素都分配给目标的相应元素
  • 目的地的额外元素将被销毁
  • GCC 4.5做得更好。通过赋值复制源的所有元素,然后销毁目标的额外元素。在两个平台上,使用案例3,然后使用resize执行相同的操作(除了一个默认构造函数resize需要)。这是一个玩具程序,它显示了我的意思

    #include <iostream>
    #include <vector>
    #include <list>
    #include <algorithm>
    using namespace std;
    
    struct A {
        A() { cout << "A()\n"; }
        A(const A&) { cout << "A(const A&)\n"; }
        A& operator=(const A&) {
            cout << "operator=\n";
            return *this;
        }
        ~A() { cout << "~A()\n"; }
    };
    
    int main() {
        list<A> source(2);
        vector<A> desrination1(3);
        vector<A> desrination2(3);
    
        cout << "Use assign method\n";
        desrination1.assign(source.begin(), source.end());
    
        cout << "Use copy algorithm\n";
        copy(source.begin(), source.end(), desrination2.begin());
        desrination2.resize(2);
    
        cout << "The End" << endl;
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    使用名称空间std;
    结构A{
    
    A(){cout如果复制整个容器,则应依赖容器复制构造函数或赋值运算符。但如果仅将容器内容从一个复制到另一个,则最好使用
    std::copy
    。 如果使用多个POD对象,则无法为每个实例保存复制构造函数调用

    您应该考虑使用共享/智能指针,这些指针只会增加复制时的引用计数器,并在修改实例时使用复制写入。

    目的地的所有元素都是 销毁。然后复制构造函数 被调用的次数与 目的地的大小。为什么

    不确定您在说什么。分配通常实现为:

     template<class Iterator>
     void assign(Iterator first, Iterator last)
     {
          erase(begin(), end()); // Calls the destructor for each item
          insert(begin(), first, last); // Will not call destructor since it should use placemenet new
     }
    

    我几乎从不在自己的代码中复制容器(这似乎不是必须要做的事情),所以我从来没有真正考虑过这个问题。@关于如何复制STL容器的问题?我在
    copy(source.begin(),source.end(),destination.size());
    。假设
    std::copy()
    (我永远也不会明白输入这五个字符有什么困难,因为这五个字符太清晰了),第三个参数是完全错误的。我不同意
    std::copy
    constainer::assign
    更适合赋值。使用
    copy
    必须手动设置容器的大小,以适应源的大小,否则
    clear()
    并使用插入迭代器。在第一种情况下,如果目标大于源,则必须创建默认的已初始化元素(如果可能的话,所包含的元素不需要实现默认构造函数)待以后重写。在第二种情况下,清除容器后,可能需要多次分配才能重新增长。在
    assign
    的情况下,通常有更多可用信息:实现知道容器类型、元素数量(如果迭代器是随机迭代器)以及初始值(如果需要增长),以及容器的状态。该信息在
    std::copy
    中不可用,或者在源文件大小的情况下无法很好地使用。我看到了什么?请更具体地说明我的文章中您认为不正确的部分。
    assert(source.size() <= destination.size());
    destination.erase(copy(source.begin(), source.end(), destination.begin()), destination.end());
    
    class A
    {
         A& operator=(A other)
         {
             std::swap(*this, other);
             return *this;
         }
    
         // Same thing but a bit more clear
         A& operator=(const A& other)
         {
             A temp(other); // copy assignment
             std::swap(*this, temp);
             return *this;
         }
    }