美文网首页
The C++ standard library(侯捷/孟岩 译

The C++ standard library(侯捷/孟岩 译

作者: Ewitter | 来源:发表于2019-06-01 10:28 被阅读0次

    7.1 迭代器头文件

    所有容器定义各自的迭代器类型,使用某容器迭代器时不需包含特定文件。
      但有些迭代器,如逆向迭代器,被定义于头文件<iterator>中。
    

    7.2 iterator categories

    p7-1.png t7-1.png
    7.2.1 input iterator

    input iterator只能一次一个地向前读取元素。
    一旦input stream读入一个字后,下次读取时就返回另一个字。

    t7-2.png
    使用前置运算性能更好。
    7.2.2 output iterator
    t7-3.png
    note:output iterator无comparison操作,无法检验output迭代器是否有效或“写入”是否成功。
    7.2.3 forward iterator

    forward iterator是input iterator的全部功能和部分output iterator功能。


    t7-4.png

    与input/output iterator不同,forward iterator能多次指向同一群集的同一元素,并能进行多次处理。

    output iterator不支持检查是否到达序列尾端。
    
    对forward 迭代器解引用时需确保其有效性。
    
    7.2.4 bidirectional iterator

    bidirectional iterator在forward iterator基础上增加了对逆向遍历的支持,即支持递减操作符。


    t7-5.png
    7.2.5 random access iterator

    random access iterator在bidirectional iterator基础上支持随机存取。即支持“迭代器算术运算”。
    以下对象/类型支持random access iterator:

    • 可随机存取的容器(vector/deque)
    • string (字符串,string ,wstring)
    • 一般array(指针)


      t7-6.png
    // 说明random access iterator的特殊方法
    // iter/itercat.cpp
    
    #include <vector>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        vector<int> col1;
    
        // insert elements from -3 to 9
        for (int i = -3; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        /* print number of elements by processing the distance between beginning and end
         * - NOTE: uses operator- for iterators
         */
        cout << "number/distance: " << col1.end() - col1.begin() << endl;
    
        /* print all elements
         * - NOTE: uses operator < instead of operator !=
         */
        vector<int>::iterator pos;
        for (pos = col1.begin(); pos < col1.end(); ++pos)
        {
            cout << *pos << ' ';
        }
        cout << endl;
    
        /* print all elements 
         * - NOTE: uses operator[] instead of operator *
         */
        for (int i = 0; i < col1.size(); ++i)
        {
            cout << col1.begin()[i] << ' ';
        }
        cout << endl;
    
        /* print every second element
         * - NOTE: uses operator +=
         */
        for (pos = col1.begin(); pos < col1.end() - 1; pos += 2)
        {
            cout << *pos << ' ';
        }
        cout << endl;
    }
    
    程序说明:有NOTE标识的操作只适用于random access iterator。
    
    output: itercat.png
    7.2.6 vector迭代器increment / decrement

    一般可递增或递减暂时性iterator,但对于vector/string则不行。

    eg:
    vector<int> col;
    //...
    if (col.size() > 1){
        sort(++col.begin(), col.end() );
    }
    
    通常编译sort()会失败,若换deque取代vector则可通过编译,
      有时vector也可通过编译——取决于vector具体实现。
    
    为保证可移植性,应使用辅助对象,相关结构改成:
    if (col.size()  > 1){
        vector<int>::iterator beg = col.begin();
        sort(++beg, col.end() );
    }
    

    主要原因:vector iterator常被实现为一般指针,C++不允许修改任何 基本类型(含指针)的暂时值,对struct/class则可以。

    7.3 迭代器相关辅助函数

    C++标准库为迭代器提供三个辅助函数:advance()、distance()、iter_swap()。

    7.2.1 advance() 可使迭代器前进/后退
    #include <iterator>
    void advance (InputIterator& pos, Dist n)
    
    使input iterator前进/后退 n个元素;
    对bidirectional/random access iterator,n可为负值表后退;
    Dist是template类型。通常 是整数,因为会调用<、++、--等,及和0比较;
    
    不检查迭代器是否超过end(),
      因为迭代器通常不知道其所操作的容器。
    
    对random access iterator,advance()调用pos+=n,
      对其它类型迭代器则调用++pos或--pos共n次。
    

    若希望程序能方便更换容器和迭代器种类,应用advance()而不是operator+=。

    但对于不提供random access iterator的容器,性能会变差。
      另,advance()无返回值,operator+=有返回值,后者更强大。
    
    eg:
    // advance()运用示例
    // iter/advance1.cpp
    
    #include <iostream>
    #include <list>
    #include <algorithm>
    using namespace std;
    
    int main()
    {
        list<int> col1;
    
        // insert elements from 1 to 9
        for (int i = 1; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        list<int>::iterator pos = col1.begin();
    
        // print actual element
        cout << *pos << endl;
    
        // step one element backward
        advance (pos , -1);
    
        // print actual element
        cout << *pos << endl;
    
        // step three element forward
        advance (pos , 3);
    
        // print actual element
        cout << *pos << endl;
    }
    
    output: advance1.png
    7.3.2 distance()处理迭代器间的距离
    #include <iterator>
    Dist distance (InputIterator pos1, InputIterator pos2)
    
    返回input iterator pos1和pos2的距离;
    pos1和pos2须指向同一容器;
    若不是random access iterator,则从pos1须能到达pos2;
    返回值Dist类型有迭代器决定:iterator_traits<InputIterator>::difference_type
    
    对于random iterator直接返回pos2-pos1,
      对于其它iterator则不断递增pos1直到pos2止,然后返回递增次数。
    
    eg:
    // distance()示例
    // iter/distance.cpp
    
    #include <iostream>
    #include <list>
    #include <algorithm>
    using namespace std;
    
    int main()
    {
        list<int> col1;
    
        // insert elements from -3 to 9
        for (int i = -3; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        // search elements with value 5
        list<int>::iterator pos;
        pos = find(col1.begin(), col1.end(),    // range
                5); // value
    
        if (pos != col1.end() )
        {
            // process and print difference from the beginning 
            cout << "difference between beginning and 5: "
                << distance(col1.begin(), pos) << endl;
        }
        else
        {
            cout << "5 not found" << endl;
        }
    }
    
    output: distance.png

    同advance(),若希望方便更换容器类型和迭代器类型,应用distance()而不是operator-。
    对non-random iterator,当pos1在pos2之后时,会导致未定义行为。

    7.3.3 iter_swap()可交换两迭代器所指内容
    #include <algorithm>
    void iter_swap (ForwardIterator1  pos1, ForwardIterator2  pos2)
    交换pos1和pos2所指的值;
    pos1和pos2的类型不必相同但所指的两个值必须可相互赋值。
    
    eg:
    // iter/swap1.cpp
    
    #include <iostream>
    #include <list>
    #include "../stl/print.hpp"
    using namespace std;
    
    int main()
    {
    
        list<int> col1;
    
        // insert elements from 1 to 9
        for (int i = 1; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        PRINT_ELEMENTS(col1);
    
        // swap first and second value
        iter_swap (col1.begin(), ++col1.begin());
    
        PRINT_ELEMENTS(col1);
    
        // swap first and last value
        iter_swap(col1.begin(), --col1.end());
    
        PRINT_ELEMENTS(col1);
    }
    
    output: swap1.png

    7.4 Iterator adapter

    此类特殊迭代器使得算法能够以reverse mode / insert mode进行工作,也可和stream搭配工作。

    7.4.1 reverse iterator

    reverse iterator是一种配接器,重定义递增、递减运算,使其行为正好相反。

    // iter/reviter1.cpp
    
    #include <iostream>
    #include <list>
    #include <algorithm>
    using namespace std;
    
    void print (int elem)
    {
        cout << elem << ' ';
    }
    
    int main()
    {
        list<int> col1;
    
        // insert elements from 1 to 9
        for (int i = 1; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        // print all elements in normal order
        for_each (col1.begin(), col1.end(),     // range
                print); // operation
        cout << endl;
    
        // print all elements in reverse order
        for_each (col1.rbegin(), col1.rend(),   // range
                print); // operation
        cout << endl;
    }
    
    output: reviter1.png
    • 迭代器和逆向迭代器
      可将一般迭代器转换为reverse iterator,但那个迭代器须可双向移动。且,转换前后迭代器的逻辑位置发生了变化
    // iter/reviter2.cpp
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    int main()
    {
        vector<int> col1;
    
        // insert elements from 1 to 9
        for (int i = 1; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        // find position of element with value 5
        vector<int>::iterator pos;
        pos = find (col1.begin(), col1.end(), 5);
    
        // print value to which iterator pos refers
        cout << "pos: " << *pos << endl;
    
        // convert iterator to reverse iterator rpos
        vector<int>::reverse_iterator rpos(pos);
    
        // print value to which reverse iterator rpos refers
        cout << "rpos: " << *rpos << endl;
    }
    

    output:

    reviter2.png
    迭代器转换为reverse iterator后逻辑位置变化的原因:区间半开性,即实际上reverse iterator倒置了半开原则。
    p7-3.png p7-4.png
    rbegin() 即 container::reverse_iterator(end() ),
    rend() 即 container::reverse_iterator(begin() )。

    但若是一对迭代器定义的区间,变换操作就很简单且元素有效。
    // iter/reviter3.cpp
    
    #include <iostream>
    #include <deque>
    #include <algorithm>
    using namespace std;
    
    void print(int elem)
    {
        cout << elem << ' ';
    }
    
    int main()
    {
        deque<int> col1;
    
        // insert elements from 1 to 9
        for (int i = 1; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        // find position of element with value 3
        deque<int>::iterator pos1;
        pos1 = find (col1.begin(), col1.end(), 2);
    
        // find positon of element with value 7
        deque<int>::iterator pos2;
        pos2 = find (col1.begin(), col1.end(), 7);
        
        // print all elements in range [pos1, pos2)
        for_each (pos1, pos2, print);
        cout << endl;
    
        // convert iterator to reverse iterator
        deque<int>::reverse_iterator rpos1(pos1);
        deque<int>::reverse_iterator rpos2(pos2);
    
        // print all elements in range [pos1, pos2) in reverse order
        for_each (rpos2, rpos1, print);
        cout << endl << endl;
    
        for_each (rpos1, rpos2, print);
        cout << endl;
    }
    
    output: reviter3.png
    • base()将reverse iterator转换为 一般迭代器
      base()函数可见STL源码剖析。
    // iter/reviter4.cpp
    
    #include <iostream>
    #include <list>
    #include <algorithm>
    using namespace std;
    
    int main()
    {
        list<int> col1;
    
        // insert elements from 1 to 9
        for (int i = 1; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        // find position of element with value 5
        list<int>::iterator pos;
        pos = find (col1.begin(), col1.end(), 5);
    
        // print value of the element
        cout << "pos: " << *pos << endl;
    
        // convert iterator to reverse iterator
        list<int>::reverse_iterator rpos(pos);
    
        // print value of the element to whcih the reverse iterator refers
        cout << "rpos: " << *rpos << endl;
    
        // convert reverse iterator back to normal iterator
        list<int>::iterator rrpos;
        rrpos = rpos.base();
    
        // print value of the element to which the normal iterator refers
        cout << "rrpos: " << *rrpos << endl;
    }
    
    output: reviter4.png
    7.4.2 insert iterator

    也称为inserter。通过inserter,算法可insert而非overwrite。
    inserter隶属于output iterator,故只提供assignment。

    通常算法会赋值给iterator,如copy()算法:
    namespace std
    {
        template<class Inputiterator, class Outputiterator>
        Outputiterator copy (Inputiterator from_pos,  // beginning of source
                            Inputiterator from_end,  // end of source
                            OutputIterator to_pos)  // beginning of dest
        {
            while (from_pos != from_end)
            {
                *to_pos = *from_pos;  / copy value
                ++from_pos;  // increment iterator
                ++to_pos;
            }
        }
    }
    
    note: *to_pos = value;语句,insert iterator将此类赋值操作转化为插入操作。
        对于insert iterator的转化过程:
          首先operator* 返回iterator当前位置(insert iterator中视为一个 no-op,只简单传回*this。),
          然后operator=赋值(调用容器的push_back()/push_front()/insert() )。
    
    t7-7.png
    • insert iterator种类
      t7-8.png
      由于push_back()只存在于vector/deque/list/string中,故C++标准库中只有这些容器支持back_inserter。
    // iter/backins.cpp
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include "../stl/print.hpp"
    using namespace std;
    
    int main()
    {
        vector<int> col1;
    
        // create back inserter for col1
        // - inconvenient way
        back_insert_iterator<vector<int> > iter(col1);
    
        // insert element with the usual iterator interface
        *iter = 1;
        iter++;
        *iter = 2;
        iter++;
        *iter = 3;
    
        PRINT_ELEMENTS(col1);
    
        // create back inserter and insert elements
        // - convenient way
        back_inserter(col1) = 44;
        back_inserter(col1) = 55;
    
        PRINT_ELEMENTS(col1);
    
        // use back inserter to append all elements again
        // - reverse enough memory to avoid realllocation
        col1.reserve(2*col1.size() );
        copy(col1.begin(), col1.end(),  // source
                back_inserter(col1) );  // destination
    
        PRINT_ELEMENTS(col1);
    }
    
    output: backins.png

    同理push_front()只在deque/list中有实现,故front_inserter()只支持deque/list。

    // iter/frontins.cpp
    
    #include <iostream>
    #include <list>
    #include <algorithm>
    #include "../stl/print.hpp"
    using namespace std;
    
    int main()
    {
        list<int> col1;
    
        // create front inserter for col1
        // - inconvenient way
        front_insert_iterator<list<int> > iter(col1);
    
        // insert elements with the usual iterator interface
        *iter = 1;
        iter++;
        *iter = 2;
        iter++;
        *iter = 3;
    
        PRINT_ELEMENTS(col1);
    
        // create front inserter and insert elements
        // - convenient way
        front_inserter(col1) = 44;
        front_inserter(col1) = 55;
    
        PRINT_ELEMENTS(col1);
    
        // use front inserter to insert all elements again
        copy (col1.begin(), col1.end(), front_inserter(col1));
    
        PRINT_ELEMENTS(col1);
    }
    
    output: frontins.png

    general inserter根据两个参数初始化:容器和待插入位置。

    所有容器都提供insert(),故适用于所有容器,
      注意“待插入位置”对关联式容器只是提示。
    
    插入操作完成后,general inserter会获得被插入元素的位置,即
        pos = container.insert(pos, value);
        ++pos;
    如此是为了确保该迭代器的位置始终有效。
    
    // iter/inserter.cpp
    
    #include <iostream>
    #include <set>
    #include <list>
    #include "../stl/print.hpp"
    
    using namespace std;
    
    int main()
    {
        set<int> col1;
    
        // create insert iterator for col1;
        // - inconvenient way
        insert_iterator<set<int> > iter(col1, col1.begin());
    
        // insert elements with the usual iterator interface
        *iter = 1;
        iter++;
        *iter = 2;
        iter++;
        *iter = 3;
    
        PRINT_ELEMENTS(col1, "set: ");
    
        // create inserter and insert elements
        // - convenient way
        inserter(col1, col1.end()) = 44;
        inserter(col1, col1.end()) = 55;
    
        PRINT_ELEMENTS(col1, "set: ");
    
        // use inesrter to insert all elements into a list
        list<int> coll2;
        copy(col1.begin(), col1.end(), inserter(coll2, coll2.begin()));
    
        PRINT_ELEMENTS(coll2, "list: ");
    
        // use inserter to reinsert all elements into the list before the second element
        copy (col1.begin(), col1.end(), inserter(coll2, ++coll2.begin()));
    
        PRINT_ELEMENTS(coll2, "list: ");
    }
    
    output: inserter.png
    7.4.3 stream iterator

    一个istream iterator可从input stream中读,
    一个ostream iterator可对output stream写。

    • ostream iterator
      ostream iterator与insert iterator类似,区别在于ostream迭代器将赋值操作转化为operator<<。
      t7-9.png
    // iter/ostriter.cpp
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    using namespace std;
    
    int main()
    {
        // create ostream iterator for stream cout
        // - value are separated by a newline charcter
        ostream_iterator<int> intWriter(cout, "\n");
    
        // write elements with the usual iterator interface
        *intWriter = 42;
        intWriter++;
        *intWriter = 77;
        intWriter++;
        *intWriter = -5;
    
        // create collection with elements from 1 to 9
        vector<int> col1;
        for (int i = 1; i <= 9; ++i)
        {
            col1.push_back(i);
        }
    
        // write all elements without any delimiter
        copy(col1.begin(), col1.end(), ostream_iterator<int>(cout) );
        cout << endl;
    
        // write all elements with "<" as delimiter
        copy(col1.begin(), col1.end(), ostream_iterator<int>(cout, "<") );
        cout << endl;
    }
    

    output:

    ostriter.png
    note:分隔符delimiter类型是const char*,若传入一个string对象,须调用c_str()成员函数以获得正确类型。
    • istream iterator
    产生istream iterator须提供一个input stream作为参数,iterator从中读数据。
    
    然而,读操作可能失败(文件尾部或读错误等原因),算法也需直到区间是否到终点。
      故可用一个end-of-stream迭代器,该迭代器有istream的default ctor生成,
        只要任何一个读取失败,则所有istream iterator会变成end-of-stream iterator。
        故每次读操作后,须将istream iterator和end-of-istream iterator比较。
    
    t7-10.png

    两个istream iterator相等条件:

    二者都是end-of-stream iterator或 二者都可进行读操作且指向相同stream。
    
    // iter/istriter.cpp
    
    #include <iostream>
    #include <iterator>
    using namespace std;
    
    int main()
    {
        // create istream iterator that reads integers from cin
        istream_iterator<int> intReader(cin);
    
        // create end-of-stream iterator
        istream_iterator<int> intReaderEOF;
    
        /* while able to read tokens with istream iterator
         * write them twice
         */
        while (intReader != intReaderEOF)
        {
            cout << "once: " << *intReader << endl;
            cout << "once again: " << *intReader << endl;
            ++intReader;
        }
    }
    
    output: image.png

    stream iterator的另个例子:

    // iter/advance2.cpp
    
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <iterator>
    using namespace std;
    
    int main()
    {
        istream_iterator<string> cinPos(cin);
        ostream_iterator<string> coutPos(cout, " ");
    
        /* while input is not at the end of the file
         * - write every third string
         */
        while (cinPos != istream_iterator<string>() )
        {
            // ignore the following two string
            advance(cinPos, 2);
    
            // read and write the third string
            if (cinPos != istream_iterator<string>())
            {
                *coutPos++ = *cinPos++;
            }
        }
        cout << endl;
    }
    
    output: advance2.png

    7.5 iterator traits

    根据不同iterator对operation重载,具体实现通过iterator tag和trait(由<iterator>提供)实现重载。
    C++标准库为每种iterator提供一个iterator tag作为其label:

    namespace std
    {
        struct output_iterator_tag{};
        struct input_iterator_tag{};
        struct forward_iterator_tag : public input_iterator_tag{};
        struct bidirectional_iterator_tag : public forward_iterator_tag{};
        struct random_access_iterator_tag : public bidirectional_iterator_tag{};
    }
    

    若进行泛型编程,需要了解iterator所指元素类型,C++标准库提供一种template结构定义 iterator trait:

    namespace std
    {
        template<class T>
        struct iterator_traits
        {
            typedef typename T::value_type  value_type;
            typedef typename T::difference_type  difference_type;
            typedef typename T::iterator_category  iterator_category;
            typedef typename T::pointer pointer;
            typedef typename T::reference  reference;
        };
    }
    
    7.5.1 为iterator编写泛型函数
    • 运用iterator type
    eg1:以元素类型为类型的零时变量。
        typename std::iterator_traits<T>::value_type tmp;
    
    eg2:元素环形移动。
    template<class Forwarditerator>
    void shift_left (Forwarditerator beg, Forwarditerator end)
    {
        // temporary variable for first element
        typedef typename
          std::iterator_traits<Forwarditerator>::value_type value_type;
        
        if (beg != end)
        {
            // save value of first element
            value_type tmp(*beg);
            // shift following values
            //...
        }
    }
    
    • 运用iterator category
      对不同iterator类型进行不同的实现,需两步:
    1. 把template函数将iterator类型做为参数,调用另个函数。eg:
        template <class iterator>
        inline void foo(iterator beg, iterator end)
        {
            foo(beg,end,
                std::iterator_traits<iterator>::iterator_category() );
        }
    
    2. 针对不同iterator实现不同的 步骤一中所调用的函数。
        只有“非派生自其它iterator类型”的iterator类型,才要提供特殊版本。eg:
        // foo() for bidirectional iterator
        template <class BiIterator>
        void foo(BiIterator beg, BiIterator end, 
                  std::bidirectioanl_iterator_tag){  // ...}
    
        // foo() for random access iterator
        template <class RaIterator>
        void foo (RaIterator beg, RaIterator end, 
                  std::random_access_iterator_tag){  //...}
    
    • distance() 实现
    // general distance()
    template <class iterator>
    typename std::iterator_traits<iterator>::difference_type
    distance (iterator pos1, iterator pos2)
    {
        return distance(pos1, pos2,
                std::iterator_traits<iterator>::iterator_category() );
    }
    
    // distance() for random access iterator
    template <class Raiterator>
    typename std::iterator_traits<Raiterator>::difference_type
    distance (Raiterator pos1, Raiterator pos2,
            std::random_access_iterator_tag)
    {
        return pos2 - pos1;
    }
    
    // distance() for input,forward, and bidirectional iterator
    template <class Initerator>
    typename std::iterator_traits<Initerator>::difference_type
    distance(Initerator pos1, Initerator pos2,
            std::input_iterator_tag)
    {
        typename std::iterator_traits<Initerator>::difference_type d;
        for ( d = 0; pos1 != pos2; ++pos1, ++d){;}
        return d;
    }
    
    7.5.2 user-defined iterator

    自定义iterator需要为iterator提供traits,有两种可行方法:

    • 1. 提供一个特殊版本的iterator_traits结构。
    • 2. 提供必要的五种类型定义,如iterator_traits结构所述。
    C++标准库提供了一个特殊的基础类别iterator<>,用于定义自定义iterator。
        class Myiterator 
            : public std::iterator<std::bidirectional_iterator_tag, 
                                  type, std::ptrdiff_t, type*, type&>{ //...};
        第一个参数定义iterator类型,第二个参数定义元素类型,第三个参数定义距离类型,
        第四个参数定义pointer类型,第五个参数定义reference类型。
        后三个参数有默认值ptrdiff_t,type*,type&。
    
    

    eg:关联式容器的insert iterator

    // 关联式容器的 insert iterator
    // iter/assoiter.hpp
    
    #include <iterator>
    
    /* template class for insert iterator for associative containers */
    template <class Container>
    class asso_insert_iterator :
        public  std::iterator<std::output_iterator_tag, void, void, void, void>
    {
        protected:
            Container& container;   //container in which element are inserted
        
        public:
            // constructor
            explicit asso_insert_iterator (Container& c) : container(c){}
    
            // assignment operator
            // - inserts a value into the container
            asso_insert_iterator<Container>&
                operator= (const typename Container::value_type& value)
                {
                    container.insert(value);
                    return *this;
                }
    
            // dereference is a no-op that returns the iterator itself
            asso_insert_iterator<Container>& operator*() 
            {
                return *this;
            }
    
            // increment operation is a no-op that returns the iterator itself
            asso_insert_iterator<Container>& operator++()
            {
                return *this;
            }
            asso_insert_iterator<Container>& operator++(int)
            {
                return *this;
            }
    };
    
    /* convenience function to create the inserter */
    template <class Container>
    inline asso_insert_iterator<Container> asso_inserter(Container& c)
    {
        return asso_insert_iterator<Container>(c);
    }
    
    
    使用:
    // iter/assoiter.cpp
    
    #include <iostream>
    #include <set>
    #include <algorithm>
    using namespace std;
    
    #include "../stl/print.hpp"
    #include "assoiter.hpp"
    
    int main()
    {
        set<int> col1;
    
        // create inserter for col1
        // -inconvenient way
        asso_insert_iterator<set<int> > iter(col1);
    
        // insert elements with the usual iterator interface
        *iter = 1;
        iter++;
        *iter = 2;
        iter++;
        *iter = 3;
    
        PRINT_ELEMENTS(col1);
    
        // create inserter for col1 and insert elements
        // - convenient way
        asso_inserter(col1) = 44;
        asso_inserter(col1) = 55;
    
        PRINT_ELEMENTS(col1);
    
        // use inserter with an algorithm
        int vals[] = {33, 67, -4, 13, 5, 2};
        copy(vals, vals + sizeof(vals)/sizeof(vals[0]), asso_inserter(col1));
        PRINT_ELEMENTS(col1);
    }
    
    output: assoiter.png

    相关文章

      网友评论

          本文标题:The C++ standard library(侯捷/孟岩 译

          本文链接:https://www.haomeiwen.com/subject/rztvtctx.html