容器类提供的insert方法

来源:互联网 发布:现代企业管理网络课程 编辑:程序博客网 时间:2024/05/21 08:46

对于Container类,STL提供了3个重载(不同的容器可能不同,这里针对vector说明):

 

1a.insert(p,t)  p---a中有效的iterator    元素。  t插入到p的前面

 

2a.insert(p,n,t) 和上面(1)类似,多出的n是表示元素的个数。在p的前面插入nt

 

3a.insert(p,i , j) 和(2)一样,也是区间插入。pa中有效的iteratori j inputiterator类型。作用是将区间[i ,j)插入到iterator p之前。

 

看起来没什么问题。但是当我们写自己的全新的Sequence时,要知道STL实现这个的细节。这里主要是说(2)(3)两个区间插入方法的区别。

 

我们先来看看一个情况:如果我们要在vector<int>中批量插入int变量。例如,我们想在vector的开头插入100,我们可能都会这样写:v.insert(v.begin(), 10, 0)

 

实际上会出现什么情况呢?编译器处理,并不是我们想得到的结果。我们想的是调用上述的第二种方法来插入,但是编译器会选择第三种方法,而不是第二种方法。为什么会这样?

 

我们来看看vector类模板关于insert函数的定义:

 

iterator insert( iterator loc, const TYPE& val );

 

      void insert( iterator loc, size_type num, const TYPE& val );

 

   template<TYPE> void insert( iterator loc, input_iterator start, input_iterator end );

  对应的就是上面我们列出的123三种方法。我们可以看到方法二的第二个参数是size_type(注意,size_type实际上就是我们常见的size_t类型)也就是unsigned int,而我们传入的参数是2int类型变量(100)。因此如果编译器判断用方法二,就要进行类型转换。但是看看方法三的原型,和我们的调用完全复合。第一个参数为iterator;后面2个参数都是input_iterator类型。注意C++编译器是不知道所谓的concepts的。insert(方法三)虽然拥有名为input_iterator的模板参数型别,但是该名称在这里并没有什么特殊意义。编译器并不知道insert的参数必须是个input_iterator。它只要保证后面2个参数的类型一致就行(至于后面能否成功调用,是函数调用执行过程中的事情了)。

在我们的自定义Sequence Container中,为了解决这个问题,我们可以通过常用的重载方法来实现,例如:重载insert函数,使得第二个参数为int类型:

void insert( iterator loc,int  num, const TYPE& val );

当然你可以重载很多其它的,例如改size_typefloat或者其它的类型,都可以。

 

 

 

不过,我们可以利用前面STL所用到的Type Dispatch方法来实现,这也是某些算法所用到的思想,检查insert的引数是否为整数,如果是,就采用相应的版本。

Standard C++ Lib中的numeric_limits 类,可以很方便的用来检查某个类型是否为整数。

template< bool x > // nontype template parameters

 

  struct dumy

 

  {};

 

 

 

  template< class T >

 

  struct my_Sequence

 

  {

 

     void fill_insert(iterator, size_type, const value_type&);

 

    

 

     template< class InputIter >

 

     void range_insert(iterator, InputIter, InputIter);

 

    

 

     template< class Number >

 

     void insert(iterator p, Number n, Number t, dumy<true>)

 

     {

 

         fill_insert(p,n,t);

 

     }

 

     template< class InputIter >

 

     void insert(iterator p, InputIter first, InputIter last, dumy<false>)

 

     {

 

         fill_insert(p, first, last);

 

     }

 

    

 

     void insert(iterator p, size_type n, const value_type& t)

 

     {

 

         fill_insert(p,n,t);

 

     }

 

    

 

     template< class InputIter >

 

     void insert(iterator p, InputIter first, InputIter last)

 

     {

 

        insert(p, first, last , dumy<std::numeric_limits<InputIter>::is_integer>());

 

     }

 

  };

之所以做了这么多的额外工作,还是为了一点,提高效率。因为这个在编译的时候进行判断,而不是在运行时期通过if else进行判断,大大节省了程序运行时间。(注:使用numeric_limits类,我们需要包含头文件limits

原创粉丝点击