STL技术整理
STL一些新的特性关键字。
STL的allocator,accumulate
做内存池管理的话,考虑allocator吧。
//-----------------------------------------
#include <numeric>
#include <vector>
#include <functional>
#include <iostream>
//-----------------------------------------
using namespace std;
//-----------------------------------------
// 自己的处理函数
int MyFun( const int& p_nA, const int& p_nB )
{
return p_nA * 10 + p_nB;
}
//-----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
// 内存分配器管理
typedef vector< int, allocator<int> >::iterator Ite;
int nArrayList[10] = {1,2,3,4,5,6,7,8,9,10};
// vector构造函数
// 可用vector< int, allocator<int> > v1( nArrayList, nArrayList + 10 );替代。但推荐下面代码,安全系数高。
vector< int, allocator<int> > v1( &nArrayList[0], &nArrayList[10] );
// 第三个参数为初始值,可以认为 accumulate( Begin, End, BeginValue, plus<int>() )
// 结果为 BeginValue + Begin + End
// 第四个参数为函数地址,可使用自定义函数地址,不填写则默认为 plus< T > 求和。
int nSum = accumulate( v1.begin(), v1.end(), 0, plus<int>());
int nProd = accumulate(v1.begin(), v1.end(), 1, multiplies<int>());
int nMin = accumulate(v1.begin(), v1.end(), 11, minus<int>());
int nDivi = accumulate(v1.begin(), v1.begin()+2, 1, divides<int>());
int nMySelf = accumulate(v1.begin(), v1.end(), 0, MyFun );
for( Ite i = v1.begin(); i != v1.end(); ++i )
{
cout << *i << endl;
}
cout << "总和 = " << nSum << endl;
cout << "累积 = " << nProd << endl;
cout << "总减 = " << nMin <<endl;
cout << "累除 = " << nDivi << endl;
cout << "自己 = " << nMySelf << endl;
int nWaitNum = 0;
cin >> nWaitNum;
return 0;
}
STL的adjacent_difference
//-----------------------------------------
#include <numeric>
#include <vector>
#include <functional>
#include <iostream>
//-----------------------------------------
using namespace std;
//-----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
int nArray[10] = { 1,1,2,3,5,8,13,21,34,55 };
vector< int, allocator<int> > v( nArray, nArray + 10 );
vector< int, allocator<int> > diffs( 10 );
vector< int, allocator<int> > prods( 10 );
// 对相邻元素求差,填充至第三个容器参数中。(默认为minus)
adjacent_difference( v.begin(), v.end(), diffs.begin() );
// 对相邻元素求积,填充至第三个容器参数中。同样,可以自定义函数进行处理。
// 可参见上一篇 闲的蛋疼1……STL的allocator,accumulate
// http://hi.baidu.com/freedomknightduzhi/blog/item/34a4d9036bc91ae108fa93ad.html
// 和上一篇不同的是,accumulate是将处理后的值 和 邻接的下一个元素 进行处理。
// 本篇是将两个相邻的元素进行处理。
adjacent_difference(v.begin(), v.end(), prods.begin(), multiplies<int>());
typedef vector< int, allocator<int> >::iterator Ite;
Ite i = diffs.begin();
for( ; i != diffs.end(); ++i )
{
cout << *i << endl;
}
cout << "---------------" << endl;
// 注意这里的输出方式,建议编译运行一下:)
// ostream_iterator的意义就是允许对流进行iterator的操作,从而让算法可以施于流上
copy( prods.begin(), prods.end(), ostream_iterator< int, char, char_traits<char> >( cout, " ") );
cout << endl;
int nWaitGet = 0;
cin >> nWaitGet;
}
STL的advance
//-----------------------------------------
#include <list>
#include <iterator>
#include <iostream>
//-----------------------------------------
using namespace std;
//-----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
int nArray[6] = { 3,4,5,6,7,8 };
list< int, allocator<int> > l( &nArray[0], &nArray[6] );
copy( l.begin(), l.end(), ostream_iterator<int, char, char_traits<char> >( cout, " " ) );
cout << endl;
list< int, allocator<int> >::iterator Ite = l.begin();
cout << *Ite << endl;
// + 符不支持前置迭代器,所以使用advance,对于List这样内存不连续容器,advance跳跃访问蛮不错的
advance( Ite, 4 );
cout << *Ite << endl;
int nWaitGet = 0;
cin >> nWaitGet;
}
STL的auto_ptr
//-----------------------------------------
#include <memory>
#include <iostream>
//-----------------------------------------
using namespace std;
//-----------------------------------------
struct STest
{
STest( int p_nI = 0 )
: m_nI( p_nI )
{
}
int GetI() const
{
return m_nI;
}
private:
int m_nI;
};
//-----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
auto_ptr< STest > pTestObj( new STest(19840515) );
auto_ptr< STest > pTestObj2 = pTestObj;
STest* pOldObjPtr = new STest(19880927);
auto_ptr< STest > pTestObj3( pOldObjPtr ); // 隐式转换
// cout << pTestObj->GetI() << endl; // 会当掉。原因参见注意4
cout << pTestObj2->GetI() << endl;
cout << pTestObj3->GetI() << endl;
// 这里,我们不用负责对指针的删除。auto_ptr会知道什么时候去删除。
// 注意的几点:
// 1:auto_ptr 在析构时会释放其管理的对象。所以两个auto_ptr不允许拥有同样的一个对象。
// 例如:auto_ptr< STest > pTestObj3( pOldObjPtr ); auto_ptr< STest > pTestObj4( pOldObjPtr ); 是禁止的。
// 两个auto_ptr都认为对象是由自己管理,会各自析构时试图删除pOldObjPtr,出错。
// 2:因为auto_ptr 析构的时候使用的是delete,不是delete[],所以,不要用auto_ptr进行数组的管理。
// 例如:int* pArray = new int[10]; auto_ptr<int> pAuto( pArray ); 是禁止的。
// 3:explicit关键词可以禁止将一个普通裸指针隐式转换为auto_ptr类型。
// 4:auto_ptr在拷贝后,将失去对象的管理权。此时,源auto_ptr将为NULL。这点很危险,一定注意。
// 5:重要辅助函数 get() 可以获取auto_ptr所拥有的对象普通裸指针。
int nWaitNum = 0;
cin >> nWaitNum;
}
STL的fill,copy,generate,swap
//-----------------------------------------
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <iostream>
#include <sstream>
//-----------------------------------------
using namespace std;
//-----------------------------------------
string MyGenerateLabel()
{
static int nLastLabel = 0;
ostringstream ost;
ost << "L_" << nLastLabel++ << '\0';
return ost.str();
}
//-----------------------------------------
class CItoAGen
{
public:
CItoAGen( int p_nStart )
: m_nCurrent( p_nStart )
{
}
int operator() ()
{
return m_nCurrent++;
}
private:
int m_nCurrent;
};
//-----------------------------------------
void FillExampleFun();
void CopyExampleFun();
void GeneExampleFun();
void SwapExampleFun();
//-----------------------------------------
int main()
{
FillExampleFun();
CopyExampleFun();
GeneExampleFun();
SwapExampleFun();
int nWaitNum = 0;
cin >> nWaitNum;
}
//-----------------------------------------
void FillExampleFun()
{
cout << "---------- fill ----------" << endl;
char szBuffer[100];
char* pBuffer = szBuffer;
int nArray[10][10];
// 填充数组
fill( pBuffer, pBuffer + 100, '\0' );
fill_n( pBuffer, 88, 'x' );
cout << szBuffer << endl;
fill( &nArray[0][0], &nArray[9][10], 2 );
for( unsigned int i = 0; i < 10; ++i )
{
for( unsigned int j = 0; j < 10; ++j )
{
cout << nArray[i][j] << " ";
}
}
cout << endl;
// 填充链表
list< string , allocator< string > > MyList;
fill_n( inserter( MyList, MyList.begin() ), 10, "Test" );
copy( MyList.begin(), MyList.end(), ostream_iterator< string, char, char_traits<char> >( cout, " " ) );
cout << endl;
// 覆盖填充
fill( MyList.begin(), MyList.end(), "Test2" );
copy( MyList.begin(), MyList.end(), ostream_iterator< string, char, char_traits<char> >( cout, " " ) );
cout << endl;
// 填充vector
vector< int, allocator<int> > MyVec(10);
generate( MyVec.begin(), MyVec.end(), CItoAGen(1) );
copy( MyVec.begin(), MyVec.end(), ostream_iterator< int, char, char_traits<char> >( cout, " " ) );
cout << endl;
// 局部赋值
vector< int, allocator<int> > ::iterator Ite = find( MyVec.begin(), MyVec.end(), 7 );
fill( MyVec.begin(), Ite, 0 );
copy( MyVec.begin(), MyVec.end(), ostream_iterator< int, char, char_traits<char> >( cout, " " ) );
cout << endl;
}
//-----------------------------------------
void CopyExampleFun()
{
cout << "---------- copy ----------" << endl;
// 简单的copy
char* szSource = "source";
char* szDest = "dest";
char szBuffer[100];
char* szpBuffer = szBuffer;
copy( szSource, szSource + strlen( szSource ) + 1, szpBuffer );
cout << szpBuffer << endl;
// 自我拷贝
*copy( szpBuffer + 2, szpBuffer + strlen( szBuffer ), szpBuffer ) = '\0';
int nBufLen = strlen( szBuffer ) + 1;
cout << szpBuffer << endl;
copy_backward( szpBuffer, szpBuffer + nBufLen, szpBuffer + nBufLen + 3 );
cout << szpBuffer << endl;
copy( szDest, szDest + 3, szpBuffer );
// 拷贝到输出流
copy( szpBuffer, szpBuffer + strlen( szBuffer ), ostream_iterator< char, char, char_traits<char> >( cout ) );
cout << endl;
// 拷贝list
list< char, allocator<char> > CharList;
copy( szpBuffer, szpBuffer + strlen(szBuffer), inserter( CharList, CharList.end()));
copy( CharList.begin(), CharList.end(), ostream_iterator< char, char, char_traits<char> >( cout ) );
cout << endl;
char* szBig = "big";
copy( szBig, szBig + 4, inserter( CharList, CharList.begin()));
copy( CharList.begin(), CharList.end(), ostream_iterator< char, char, char_traits<char> >( cout ) );
cout << endl;
}
//-----------------------------------------
void GeneExampleFun()
{
cout << "---------- generate ----------" << endl;
list< string, allocator<string> > MyList;
generate_n( inserter( MyList, MyList.begin()), 4, MyGenerateLabel );
copy( MyList.begin(), MyList.end(), ostream_iterator< string, char, char_traits<char> >(cout, " ") );
cout << endl;
vector< int, allocator<int> > MyVec(10);
generate( MyVec.begin(), MyVec.end(), CItoAGen(2) );
copy( MyVec.begin(), MyVec.end(), ostream_iterator<int, char, char_traits<char> >(cout, " ") );
cout << endl;
generate_n( MyVec.begin(), 5, CItoAGen(10) );
copy( MyVec.begin(), MyVec.end(), ostream_iterator<int, char, char_traits<char> >(cout, " ") );
cout << endl;
}
//-----------------------------------------
void SwapExampleFun()
{
cout << "---------- swap ----------" << endl;
int nArrayData[] = { 12, 27, 14, 64 };
int* pData = nArrayData;
vector<int, allocator<int> > MyVec(4);
generate( MyVec.begin(), MyVec.end(), CItoAGen(1) );
// 数组节点交换
swap( nArrayData[0], nArrayData[2] );
copy( &nArrayData[0], &nArrayData[4], ostream_iterator< int, char, char_traits< char > >(cout, " ") );
cout << endl;
// 迭代器交换
copy( MyVec.begin(), MyVec.end(), ostream_iterator< int, char, char_traits< char > >(cout, " ") );
cout << endl;
vector<int, allocator<int> >::iterator Ite = MyVec.end();
Ite--;
iter_swap( MyVec.begin(), Ite );
copy( MyVec.begin(), MyVec.end(), ostream_iterator< int, char, char_traits< char > >(cout, " ") );
cout << endl;
// 两个容器的交换
swap_ranges( MyVec.begin(), MyVec.end(), pData );
copy (nArrayData, nArrayData+4, ostream_iterator<int,char,char_traits<char> >(cout, " "));
cout << endl;
copy (MyVec.begin(), MyVec.end(), ostream_iterator<int,char,char_traits<char> >(cout, " "));
cout << endl;
}