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;
}