容器类提供的insert方法

转载 2011年01月17日 18:55:00

对于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

相关文章推荐

容器链表中splice()、merge()、insert()方法的区别

容器链表的insert()方法和splice()方法的区别   如: #include #include using namespace std; void main() { ...

SQLiteDatabase类的query(),insert(),update(),delete()方法参数说明

1、SQLiteDataBase对象的query()接口: public Cursor query (String table, String[] columns, String selection...

STL学习之map容器(2)_insert

map::insert pair insert(const value_type& x); iterator insert(iterator posit...

map常用成员(关联容器)----创建map<主键,主键对应的值>,增insert,删erase,改查找find,然后修改second,遍历iterator,获取元素个数size,判空empty

map是STL的一个关联容器,它提供一对一(第一个字段为关键字,每个关键字只能在map中出现一次,第二个字段称为该关键字的值)的数据处理能力,由于这个特性 map内部的实现自建一颗红黑树(一种非严格...
  • ttguess
  • ttguess
  • 2012年08月13日 16:25
  • 6794

顺序容器的insert用法

#include #include #include #include #include using namespace std; //顺序容器的insert用法 //顺序容器:vecto...

《STL源码剖析》---list容器insert操作的个人理解

最近在看STL源码剖析,感觉还是挺深奥的,感觉看不太懂。今天在看list容器这块,讲到了insert操作,便记录一番自己的理解吧。        摘抄书上的:...

C++语法基础--关联容器--map(一)--constructor,operator[],insert

1关联容器类型        set和map类型的对象所包含的元素都具有不同的键,不允许为同一个键添加第二个元素 2.map类型(#include)   原型:       te...

集合类各容器方法以及细节

1、集合类各容器方法: **接口Collection方法摘要(没有构造方法)            a)添加:                                    i.  bo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:容器类提供的insert方法
举报原因:
原因补充:

(最多只允许输入30个字)