zoukankan      html  css  js  c++  java
  • 容器list使用之erase(其他容器也通用)

    今天无论如何要写点东西,算是搞清楚了一点东西吧。有点小小的成就感。
    之前在程序里面使用了list容器,其中用到了erase()函数,之前一直没出现问题,这两天突然莫名奇妙。花了点时间,搞清楚了erase()函数的机理。
    常用的删除容器中元素的方法是如下(方法1):
          list< int> List;
          list< int>::iterator iter;
          for( iter = List.begin(); iter != List.end(); )
          {
                if(1)  
                {
                   iter = List.erase( iter );
                }
                else
                {
                   iter++;
                }
          }
    
     也可以这样写(方法2):
          list< int> List;
          list< int>::iterator iter;
          for( iter = List.begin(); iter != List.end(); )
          {
                if(1)  
                {
                   List.erase( iter++ );
                }
                else
                {
                   iter++;
                }
          }
    
     有一种错误的写法(注意同方法2比较)
         list< int> List;
          list< int>::iterator iter;
          for( iter = List.begin(); iter != List.end(); )
          {
                if(1)  
                {
                   List.erase( iter );
                }
    
                iter++;
          }
    
     我们看一下erase()函数的源代码(仅列出release下的代码)。
            iterator erase(iterator _Where)
            {    // erase element at _Where
            _Nodeptr _Pnode = (_Where++)._Mynode();
    
            if (_Pnode != _Myhead)
                {    // not list head, safe to erase
                _Nextnode(_Prevnode(_Pnode)) = _Nextnode(_Pnode);
                _Prevnode(_Nextnode(_Pnode)) = _Prevnode(_Pnode);
                this->_Alnod.destroy(_Pnode);
                this->_Alnod.deallocate(_Pnode, 1);
                --_Mysize;
                }
            return (_Where);
            }
    
    函数在返回的时候,是返回当前迭代器的下一个节点。所以当 iter = List.erase( iter ); 执行以后,迭代器自动指向了下一个元素。而对于入参中的iter,所指的地址已经被销毁,所以写的时候,应该注意加上前面的iter =
    那另外的一种写法,List.erase( iter++ ); 为什么也是对的呢?
    这里研究了一下,这里需要讲一下++运算符的操作。(惭愧啊,++使用了这么多年,居然现在才搞明白)
            _Myt_iter& operator++()   
                {    // preincrement
                ++(*(_Mybase_iter *)this);
                return (*this);
                }
    
            _Myt_iter operator++(int) 
                {    // postincrement
                _Myt_iter _Tmp = *this;
                ++*this;
                return (_Tmp);
                }
    
    ++实际上可以看做是一个函数。
    对于++在后的情况(例如i++),函数在运行的时候,将运算的数据i已经改变,但是函数的返回值是操作之前的数据,所以在我们看来,i++好像是先进行了i的读取,才+1。
    
    回到迭代器,List.erase( iter++ );就没有问题了。
    
    对于那种错误的方法,List.erase( iter );在执行以后,iter所指的对象已经被销毁,所以再对iter进行操作是非法的,程序会出错。
  • 相关阅读:
    sql语句中的一些常用语法
    torch_12_BigGAN全文解读
    torch_12_dataset和dataLoader,Batchnormalization解读
    torch_11_BEGAN
    torch_11_风格迁移和cycleGAN
    torch_10_stackGAN-V2
    torch_09_DCGAN_注意的细节
    torch_09_GAN
    pytorch-04-激活函数
    torch_07_卷积神经网络案例分析
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/5892584.html
Copyright © 2011-2022 走看看