13.各种容器总结:
1). vector操作:
■ vector的删除与安插元素性能:
◆ 在容器尾部安插或者移除元素
◆ 容量一开始就够大
◆ 安插多个元素时,调用一次比调用多次来的快
■ C++对vector函数调用异常保证:
◆ 如果push_back安插时发生异常,该函数不起作用
◆ 如果元素的拷贝操作不抛出异常,那么insert要么成功,要么不生效.
◆pop_back绝不抛出异常
◆ 如果元素拷贝操作不抛出异常,erase和clear就不抛出异常
◆swap 不抛出异常
◆ 如果元素拷贝操作绝不会爬出异常,那么素有操作不是成功就是不起作用.
2). deques操作
■ deqeues与vector的不同点
◆ deques不提供容量操作(capacity()与reserve())
◆ deques直接提供函数,用以完成头部元素的安插和删除(push_front()和pop_front())
■ C++对deques函数调用异常保证:
◆ 以push_back或push_front安插元素时发生异常,则该操作不带来任何效应
◆pop_back和pop_front不会抛出任何异常
3).list操作
■ list与vector、deques的区别:
◆ list不支持随机存取,因此在list中随机遍历任意元素,是很缓慢的行为.
◆ 任何位置(不只是两端)执行元素的安插和移除都非常快
◆ 安插元素并不会造成指向其他元素的各个pointers,references.iterators失效
◆ list对于一场有着这样的处理方式,要么成功,要么什么都不发生
list的remove算法比算法库的remove算法更快.在使用时,尽量使用其自带的成员函数.
4). set操作
■ set按照排序准则排序,所谓排序准则,意义如下:
◆ 必须是反对称的.x<y为真,y<x为假
◆ 必须是可传递的.x<y,y<zèx<z
◆ 必须是自反的:x<x为假
说明:<<C++标准程序库>>书中提到set支持=操作符,不论其排序准则是否相同.这句起码在vs2010上无法运行成功.
set无法使用remove操作.原因是无法完成覆盖,因此你只能使用erase成员函数
■ set与multiset的insert区别:
pair<iterator,bool>insert(const value_type& elem)//返回pair表示安插是否成功,以及新元素的位置
multiset删除相同取值的元素:
iterator iter = contains.find(elem);
while( iter !=contains.end)
{
contains.erase(elem);
}
■ set与序列容器区别
erase:前者不返回值,后者返回删除元素的后一元素
关于erase的详细情况请参照博客: http://blog.csdn.net/yuanweihuayan/article/details/6790516
5). map操作:
■ 删除second为value的元素:
map<int,string> _map_Int_string;
_map_Int_string.insert(pair<int,string>( 1,"ysl" ) );
_map_Int_string.insert(pair<int,string>( 2,"ldh" ) );
_map_Int_string.insert(pair<int,string>( 5,"ldh" ) );
_map_Int_string.insert(pair<int,string>( 8,"ldh" ) );
_map_Int_string.insert(pair<int,string>( 4,"gfc" ) );
_map_Int_string.insert(pair<int,string>( 3,"zxy" ) );
for( map<int,string>::iteratoriterPos = _map_Int_string.begin();iterPos != _map_Int_string.end(); )
{
if ( iterPos->second =="ldh")
{
_map_Int_string.erase(iterPos ++ );
}
else
{
++iterPos;
}
}
范例:
class _functorTest
{
public:
enum cpm_enum{ normal_cpm,nonormal_cpm };
_functorTest(cpm_enum param = nonormal_cpm ):_cValue( param ){}
static bool cpm_fun( const char _left,const char _right )
{
return toupper( _left ) < toupper( _right );
}
bool operator()( const string _fLeft,conststring _fRight )
{
if ( _cValue == normal_cpm )
{
return _fLeft < _fRight;
}
else
{
return lexicographical_compare(_fLeft.begin(),_fLeft.end(),_fRight.begin(),_fRight.end(),cpm_fun );
}
}
private:
const cpm_enum _cValue;
};
int main()
{
_functorTestfun( _functorTest::nonormal_cpm );
typedef map<string,string,_functorTest >map_Functor;
map_Functor_map_owner( fun );
/* 注意此处与书上的差异 */
_map_owner.insert(make_pair( "Deutschland","Germany" ) );
_map_owner.insert(make_pair( "deutsch","German" ) );
_map_owner.insert(make_pair( "Haken","snag" ) );
_map_owner.insert(make_pair( "deutschland","enterprise" ) );
for ( map_Functor::iterator iterPos =_map_owner.begin();iterPos != _map_owner.end();++ iterPos )
{
cout<<"first :"<<iterPos->first<<" second:"<<iterPos->second<<"\n";
}
system("pause");
return 0;
}
需要详细说明的几点:
◆ cpm_fun是静态成员函数
◆ cpm_fun的参数:针对原子元素进行操作
◆ insert与=的区别:insert不会覆盖原来存在的值,而=则会.
◆ 把functorTest当做仿函数来用(类似less)
14. 需要注意的函数:reverse,reserve:前者是逆转容器.后者是备用容量,后者只有vector,string才具有的操作.
15. 代码疑惑:
istream_iterator<string>cinPos(cin);//输入一段字符
ostream_iterator<string>coutPos( cout," " );//输出一段字符,以空格分隔
while ( cinPos != istream_iterator<string>() )//输入流没有到尾部
{
advance(cinPos,2 );//取cinPos+2
if ( cinPos != istream_iterator<string>() )
{
*coutPos++= * cinPos ++;//输出
}
}
这个程序从某种角度来讲结果都是很正常.
但是问题在于按照程序输出了指定的字符串为什么后面还要用户输入?
而且我如果输入三个字符程序就无法输出.
16. 在使用仿函数或判断式(单参数)时,改判断式应该总是返回相同结果,换句话说,判断式不应该因为被调用而改变自身状态
17. 函数配接器:
◆ bind2nd:将一个二元仿函数转换为一元仿函数.通常将第二个参数传给”由第一个参数指出”的二元仿函数,作为后者的第二参数.
◆ bind1lst将一个二元仿函数转换为一元仿函数.通常将第二个参数传给”由第一个参数指出” 的二元反函数,作为后者的第一个参数.
template<class T1>
class lessFunctor:public binary_function<T1,T1,T1>
{
public:
T1 operator()( T1 compareValue,T1 const_value ) const
{
return max( compareValue,const_value );
}
};
int main()
{
vector<int> _vecInt;
for ( int i = 0;i < 10;++ i )
{
_vecInt.push_back( i );
}
transform( _vecInt.begin(),_vecInt.end(),ostream_iterator<int>( cout," " ),bind1st( lessFunctor<int>(),3 ) );
cout<<"\n";
transform( _vecInt.begin(),_vecInt.end(),ostream_iterator<int>( cout," " ),bind2nd( lessFunctor<int>(),3 ) );
system( "pause" );
return 0;
}
18. STL算法采用覆盖模式而非安插模式.
19.在string牵涉到索引的时候,应该将size_type转换为int..另外string的reserve有缩减元素功能.(和vector不同)