C++ STL原來可以這么強(qiáng)大 -電腦資料

電腦資料 時間:2019-01-01 我要投稿
【m.clearvueentertainment.com - 電腦資料】

   

    今天在做C++ Primer第14章習(xí)題14.37的時候用到了一些STL的函數(shù),徹底顛覆了我對C++的看法,

C++ STL原來可以這么強(qiáng)大

。以前總覺得C++很麻煩,實(shí)現(xiàn)一個功能總要寫一堆的代碼,很繁瑣,那是菜鳥時候的想法。雖然現(xiàn)在也還是菜鳥,但級別比原來提高了一點(diǎn),從今天使用了STL的算法之后才知道,原來C++也可以這么簡潔。

    從習(xí)題一步步擴(kuò)展開來講吧,習(xí)題如下:

    習(xí)題14.37 使用標(biāo)準(zhǔn)庫函數(shù)對象和函數(shù)適配器,定義一個對象用于:

    (a)查找大于1024的所有值

    (b)查找不大于pooth的所有字符串

    (c)將所有值乘以2

    做這題之前先簡單介紹一下C++的函數(shù)對象和標(biāo)準(zhǔn)庫提供的函數(shù)適配器。

    C++中函數(shù)對象是為實(shí)現(xiàn)某種操作而重載調(diào)用操作符的類,即重載其operator()操作符函數(shù),必須聲明為成員函數(shù)。函數(shù)對象經(jīng)常用作通用算法的實(shí)參。標(biāo)準(zhǔn)庫定義了很多函數(shù)對象供程序員使用,在functional頭文件里面定義,包含算數(shù)函數(shù)對象類型、關(guān)系函數(shù)對象類型和邏輯函數(shù)對象類型,這些函數(shù)對象有的是一元函數(shù)對象,有的是二元函數(shù)對象,一元函數(shù)對象接受一個實(shí)參,二元函數(shù)對象接受兩個實(shí)參。

    STL中提供了很多標(biāo)準(zhǔn)庫算法,一般的標(biāo)準(zhǔn)庫算法都使用內(nèi)置的操作,比如<、==等,如果要使用自定義的操作,可以傳函數(shù)指針,但對函數(shù)指針的形參個數(shù)有限制,用起來不是很方便。這時候函數(shù)對象就可以發(fā)揮作用了,可以把多余的參數(shù)作為函數(shù)對象的內(nèi)部成員,通過初始化的時候把值傳遞給函數(shù)對象,通過調(diào)用函數(shù)對象的調(diào)用操作符實(shí)現(xiàn)比較的目的。

    C++提供了函數(shù)適配器來擴(kuò)展函數(shù)對象的使用。因為二元函數(shù)對象要傳遞兩個值,如果其中有一個值是已知或者默認(rèn)的,這時候可以把他初始化,這個功能由綁定器來提供,bind1st用來綁定二元函數(shù)對象的第一個實(shí)參,bind2nd用于綁定二元函數(shù)對象的第二個實(shí)參。另外一個適配器是求反器,用于對謂詞函數(shù)對象的真值求反,not1對一元函數(shù)對象求反,not2對二元函數(shù)求反。

    簡單介紹完基礎(chǔ)之后再回來解這習(xí)題,來看看STL是怎么讓程序變得簡潔的。

    對于(a)可以用bind2nd函數(shù)適配器和greater函數(shù)對象來實(shí)現(xiàn),如下所示:

    [cpp]

    // Find the value greater than 1024 with standard function objects and function adaptor

    int nVal[] = {43, 53, 536, 4976, 5307, 32, 536, 957};

    size_t size = sizeof(nVal) / sizeof(int);

    cout << "The original value: " << endl;

    for (size_t i = 0; i != size; ++i)

    cout << nVal[i] << " ";

    cout << endl;

    int *nFind = nVal;

    int toCompare = 1024;

    cout << "The value that greater than " << toCompare << " : " << endl;

    while ((nFind = find_if(nFind, nVal + size, bind2nd(greater(), toCompare))) != nVal + size)

    {

    cout << *nFind << " ";

    ++nFind;

    }

    cout << endl << endl;

    對于(b)可以用bind2nd函數(shù)適配器和not_equal_to函數(shù)對象來實(shí)現(xiàn),如下所示:

    [cpp]

    // Find string not equal with "pooth"

    const int ARYSIZE = 5;

    string sAry[ARYSIZE] = {"abc", "adu", "butterfly", "pooth", "nancy"};

    vector sVec(sAry, sAry + ARYSIZE);

    vector::iterator sIter = sVec.begin();

    cout << "The original string: " << endl;

    while (sIter != sVec.end())

    {

    cout << *sIter << " ";

    ++sIter;

    }

    cout << endl;

    cout << "The string that not euqal with \"pooth\" : " << endl;

    sIter = sVec.begin();

    string sToCompare = "pooth";

    while ((sIter = find_if(sIter, sVec.end(), bind2nd(not_equal_to(), sToCompare))) != sVec.end())

    {

    cout << *sIter << " ";

    ++sIter;

    }

    cout << endl << endl;

    對于(c)可以用bind2nd函數(shù)適配器、transform和multiplies來實(shí)現(xiàn),如下所示:

    [cpp]

    class PrintVal

    {

    public:

    PrintVal() { }

    void operator()(int &val) const { cout << val << " "; }

    };

    // Multiply all the value by 2

    vector nVec(nVal, nVal + size);

    cout << "The original val: " << endl;

    for_each(nVec.begin(), nVec.end(), PrintVal());

    cout << endl;

    transform(nVec.begin(), nVec.end(), nVec.begin(), bind2nd(multiplies(), 2));

    cout << "After multiply by 2: " << endl;

    for_each(nVec.begin(), nVec.end(), PrintVal());

    cout << endl;

    從上面是不是可以看到,從(a)(b)到(c)是不是代碼簡潔了很多,通過引入PrintVal函數(shù)對象和for_each的使用,大大減少了代碼量,使程序看起來簡潔易懂,

電腦資料

C++ STL原來可以這么強(qiáng)大》(http://m.clearvueentertainment.com)。

    整個習(xí)題的代碼如下所示:

    [cpp]

    #include

    #include

    #include

    #include

    #include

    using namespace std;

    class PrintVal

    {

    public:

    PrintVal() { }

    void operator()(int &val) const { cout << val << " "; }

    };

    int main()

最新文章