美文网首页Exceptional C++
【Exceptional C++(1)】Iterators

【Exceptional C++(1)】Iterators

作者: downdemo | 来源:发表于2018-01-26 12:24 被阅读22次

    问题

    • 下面代码中有至少四个与iterator相关的问题,找出来
    int main()
    {
        vector<Date> e;
        copy(istream_iterator<Date>(cin), istream_iterator<Date>(), back_inserter(e) );
        vector<Date>::iterator first = find(e.begin(), e.end(), "01/01/95");
        vector<Date>::iterator last = find(e.begin(), e.end(), "12/31/95");
        *last = "12/30/95";
        copy(first, last, ostream_iterator<Date>(cout, "\n") );
        e.insert(--e.end(), TodaysDate() );
        copy(first, last, ostream_iterator(cout, "\n") );
    }
    

    说明

    • std::copy拷贝[first,last)中的元素到beginning at result
    template<class InputIterator, class OutputIterator>
      OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
    {
      while (first!=last) {
        *result = *first;
        ++result; ++first;
      }
      return result;
    }
    
    • std::istream_iterator
    // istream_iterator example
    #include <iostream>     // std::cin, std::cout
    #include <iterator>     // std::istream_iterator
    
    int main () {
      double value1, value2;
      std::cout << "Please, insert two values: ";
    
      std::istream_iterator<double> eos;              // 不指定对象即为end-of-stream iterator
      std::istream_iterator<double> iit (std::cin);   // stdin iterator
    
      if (iit!=eos) value1=*iit;
    
      ++iit;
      if (iit!=eos) value2=*iit;
    
      std::cout << value1 << "*" << value2 << "=" << (value1*value2) << '\n';
    
      return 0;
    }
    
    // output
    Please, insert two values: 2 32
    2*32=64
    
    • std::back_inserter用于尾部插入
    // back_inserter example
    #include <iostream>     // std::cout
    #include <iterator>     // std::back_inserter
    #include <vector>       // std::vector
    #include <algorithm>    // std::copy
    
    int main () {
      std::vector<int> foo,bar;
      for (int i=1; i<=5; i++)
      { foo.push_back(i); bar.push_back(i*10); }
    
      std::copy (bar.begin(),bar.end(),back_inserter(foo));
    
      std::cout << "foo contains:";
      for ( std::vector<int>::iterator it = foo.begin(); it!= foo.end(); ++it )
          std::cout << ' ' << *it;
      std::cout << '\n';
    
      return 0;
    }
    
    //output
    foo contains: 1 2 3 4 5 10 20 30 40 50
    
    • std::ostream_iterator
    // ostream_iterator example
    #include <iostream>     // std::cout
    #include <iterator>     // std::ostream_iterator
    #include <vector>       // std::vector
    #include <algorithm>    // std::copy
    
    int main () {
      std::vector<int> myvector;
      for (int i=1; i<10; ++i) myvector.push_back(i*10);
    
      std::ostream_iterator<int> out_it (std::cout,", ");
      std::copy ( myvector.begin(), myvector.end(), out_it ); // 打印元素后接分隔符
      return 0;
    }
    
    // output
    10, 20, 30, 40, 50, 60, 70, 80, 90,
    

    解答

    int main()
    {
        vector<Date> e;
        copy(istream_iterator<Date>(cin), istream_iterator<Date>(), back_inserter(e) );
        vector<Date>::iterator first = find(e.begin(), e.end(), "01/01/95");
        vector<Date>::iterator last = find(e.begin(), e.end(), "12/31/95");
        *last = "12/30/95"; // 1
        copy(first, last, ostream_iterator<Date>(cout, "\n") ); // 2
        e.insert(--e.end(), TodaysDate() ); // 3
        copy(first, last, ostream_iterator(cout, "\n") );
    }
    
    • find找不到目标会返回尾后迭代器,last可能是e.end()
    • first找不到目标返回尾后迭代器,但last找到了,这样first就可能在last之后
    • --e.end()可能不合法,vector<Date>::iterator用Date*实现,不能修改,所以要改成e.insert(e.end() - 1, TodaysDate() );
    Date* f();
    p = --f(); // 错误,但写成f()-1就可以
    
    • 如果e是空的,e.end() -1也不是有效的iterator
    • e.insert之后vector可能增长,导致iterator都失效,此时copy会产生core dump

    总结

    • 使用iterator时,思考下列问题
      • 数值:这个iterator可以dereference吗,比如尾后迭代器,*e.end()肯定错
      • 寿命:被使用时是否因为某些操作失效
      • 范围:是否有效,比如first在last之后,或者指向不同的容器
      • 行为:不合法的操作,比如--e.end()

    相关文章

      网友评论

        本文标题:【Exceptional C++(1)】Iterators

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