• 实战c++中的vector系列--再谈vector的insert()方法(都是make_move_iterator惹的祸)


    之前说过了关于vector的insert()方法,把vector B的元素插入到vector A中。vector A中的结果我们可想而知,可是vector B中的元素还会怎样?

    看看之前写过的程序:

    #include <iostream>
    #include <vector>
    
    int main ()
    {
      std::vector<int> myvector (3,100);
      std::vector<int>::iterator it;
    
      it = myvector.begin();
      it = myvector.insert ( it , 200 );
    
      myvector.insert (it,2,300);
    
      // "it" no longer valid, get a new one:
      it = myvector.begin();
    
      std::vector<int> anothervector (2,400);
      myvector.insert (it+2,anothervector.begin(),anothervector.end());
    
      int myarray [] = { 501,502,503 };
      myvector.insert (myvector.begin(), myarray, myarray+3);
    
      std::cout << "myvector contains:";
      for (it=myvector.begin(); it<myvector.end(); it++)
        std::cout << ' ' << *it;
      std::cout << '
    ';
    
      return 0;
    }

    如今关心一下别的:注意是insert后,被insert的vector为多少了:

    #include <iostream>
    #include <vector>
    
    int main()
    {
        std::vector<int> myvector(3, 100);
    
        std::vector<int> anothervector(2, 400);
    
        std::cout << "Before insert myvector is:";
        for (auto it = myvector.begin(); it<myvector.end(); it++)
            std::cout << ' ' << *it;
        std::cout << std::endl;
    
        std::cout << "Before insert anothervector is:";
        for (auto it = anothervector.begin(); it<anothervector.end(); it++)
            std::cout << ' ' << *it;
    
        std::cout << std::endl;
    
        myvector.insert(myvector.end(), anothervector.begin(), anothervector.end());
    
        std::cout << "After insert myvector is:";
        for (auto it = myvector.begin(); it<myvector.end(); it++)
            std::cout << ' ' << *it;
    
        std::cout << std::endl;
    
        std::cout << "Now the anothervector is:";
        for (auto it = anothervector.begin(); it<anothervector.end(); it++)
            std::cout << ' ' << *it;
    
        std::cout << std::endl;
    
        int myarray[] = { 501,502,503 };
        myvector.insert(myvector.begin(), myarray, myarray + 3);
    
        std::cout << "After insert myarray[] to myvector,  myvector is:";
        for (auto it = myvector.begin(); it<myvector.end(); it++)
            std::cout << ' ' << *it;
    
        std::cout << std::endl;
    
        std::cout << "After insert myarray[] to myvector,  myarray[] is:";
        for (int i = 0; i < 3; i++)
        {
            std::cout << ' ' << myarray[i];
        }
    
        return 0;
    }
    //输出:
    //Before insert myvector is : 100 100 100
    //Before insert anothervector is : 400 400
    //After insert myvector is : 100 100 100 400 400
    //Now the anothervector is : 400 400
    //After insert myarray[] to myvector, myvector is : 501 502 503 100 100 100 400 400
    //After insert myarray[] to myvector, myarray[] is : 501 502 503

    假设你看到此时,你肯定会在心里骂娘,谁还关心vector B,而且vectorB并没有变化。


    如今是时候来点猛药了。vector中放智能指针。

    之前博客也讲诉过对于vector的元素为智能指针的时候:

    #include<iostream>
    #include<vector>
    #include <memory>
    using namespace std;
    void display_vector(vector<unique_ptr<int>> &vec);
    int main()
    {
        vector<unique_ptr<int>> vec;
        unique_ptr<int> s1(new int(1));
        unique_ptr<int> s2(new int(2));
        unique_ptr<int> s3(new int(3));
        unique_ptr<int> s4(new int(4));
        vec.push_back(std::move(s1));
        vec.push_back(std::move(s2));
        vec.push_back(std::move(s3));
        vec.push_back(std::move(s4));
    
    
        unique_ptr<int> s5(new int(5));
        vector<unique_ptr<int>> des_vec;
        des_vec.push_back(std::move(s5));
        des_vec.insert(des_vec.end(), std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()));
        display_vector(des_vec);
        cout << "now, des_vec size: " << des_vec.size() << endl;
        cout << "now, vec size: " << vec.size() << endl;
    
        //display_vector(vec);
        cout << "now, vec size: " << vec.size() << endl;
        for (int i=0; i<vec.size(); i++)
        {
            cout << *vec[i] << " ";
        }
        return 0;
    }
    
    void display_vector(vector<unique_ptr<int>> &vec)
    {
        for (auto it = vec.begin(); it != vec.end(); it++)
        {
            cout << **it << endl;
        }
    }

    上面代码会崩溃。原因就是vec被insert后 。vec变得无效了,我们不能对他做什么。。。。。

    可是须要明白的是这不是insert造成的,假设copy也会造成这一的结局,事实上罪魁祸首就是make_move_iterator

    再看程序:

    #include <iostream>
    #include <list>
    #include <vector>
    #include <string>
    #include <iterator>
    
    int main()
    {
        std::list<std::string> s{ "one", "two", "three" };
    
        std::vector<std::string> v1(s.begin(), s.end()); // copy
    
        std::vector<std::string> v2(std::make_move_iterator(s.begin()),
            std::make_move_iterator(s.end())); // move
    
        std::cout << "v1 now holds: ";
        for (auto str : v1)
            std::cout << """ << str << "" ";
        std::cout << "
    v2 now holds: ";
        for (auto str : v2)
            std::cout << """ << str << "" ";
        std::cout << "
    original list now holds: ";
        for (auto str : s)
            std::cout << """ << str << "" ";
        std::cout << '
    ';
    }
    //输出:
    //v1 now holds : "one" "two" "three"
    //v2 now holds : "one" "two" "three"
    //original list now holds : ""

    最后再上一个官方程序:

    #include <iostream>     // std::cout
    #include <iterator>     // std::make_move_iterator
    #include <vector>       // std::vector
    #include <string>       // std::string
    #include <algorithm>    // std::copy
    
    int main() {
        std::vector<std::string> foo(3);
        std::vector<std::string> bar{ "one","two","three" };
    
        std::copy(make_move_iterator(bar.begin()),
            make_move_iterator(bar.end()),
            foo.begin());
    
        // bar now contains unspecified values; clear it:
        bar.clear();
    
        std::cout << "foo:";
        for (std::string& x : foo) std::cout << ' ' << x;
        std::cout << '
    ';
    
        return 0;
    }

    * 须要注意:*
    * bar.clear();*
    因此此时: bar now contains unspecified values; clear it:

  • 相关阅读:
    Fetch the result from result set
    Variable shadowing
    What is Servlet Container
    What is a servletcontext
    Inner Class
    Java中HashMap和TreeMap的区别深入理解
    枚举类
    (转载) 安卓开发学习笔记
    【C和C++】停车场系统
    【算法】常用的排序方法
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7150544.html
Copyright © 2020-2023  润新知