• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Impossible is nothing  
              愛過知情重醉過知酒濃   花開花謝終是空   緣份不停留像春風(fēng)來又走   女人如花花似夢
            公告
            日歷
            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345
            統(tǒng)計
            • 隨筆 - 8
            • 文章 - 91
            • 評論 - 16
            • 引用 - 0

            導(dǎo)航

            常用鏈接

            留言簿(4)

            隨筆分類(4)

            隨筆檔案(8)

            文章分類(77)

            文章檔案(91)

            相冊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

             

            總有一些時候,我們不能夠借助于“生成式”的初始化方法來給容器賦值,例如我們已經(jīng)有了一個數(shù)組,要把它作為初值賦給一個容器,常規(guī)的做法已經(jīng)深入人心了

            總有一些時候,我們不能夠借助于“生成式”的初始化方法來給容器賦值,例如我們已經(jīng)有了一個數(shù)組,要把它作為初值賦給一個容器,常規(guī)的做法已經(jīng)深入人心了:

            ? int init[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
            ? std::vector<int> vect(init, init + sizeof(init)/sizeof(int));

            通過兩個 sizeof 來得到數(shù)組的大小在 C 語言里面是很常見的,然而在 C++ 里面,這即便不能稱為丑陋,也絕對稱不上是好。首先其可讀性不好,其次它要進(jìn)行一次除法來得到一個本來在編譯期間就知道的數(shù)字,最后,它并不是總能用的!例如下面的例子:

            ? std::string strs[] = { "Amy", "Ralph", "Simon", "Maggie" };

            現(xiàn)在,你打算用 "sizeof " 什么來除以 "sizeof" 什么?

            其實,經(jīng)過了這么多 C++ GP 的磨練,我們很容易就會想到一個在編譯期間得到靜態(tài)數(shù)組大小的辦法,模板偏特化是我們常用的武器,在這里非常好用:

            template <class T>
            struct ArraySize
            {
            ??? static const unsigned int value = 0;
            };

            template <class T, int S>
            struct ArraySize<T[S]>
            {
            ??? static const unsigned int value = S;
            };

            就這么簡單!雖然它只對付一維數(shù)組,但是擴(kuò)展它是很容易的。不過,模板參數(shù)只能為類型,而我們需要傳入的是一個變量。好在在計算機科學(xué)里面,加一層抽象是可以解決任何問題的,我們只要加一個模板函數(shù),C++ 會自動幫我們做類型推導(dǎo):

            template <class T>
            unsigned int array_size(const T&)
            {
            ??? return ArraySize<T>::value;
            }

            現(xiàn)在我們可以輕而易舉的搞定那些數(shù)組了:

            ? int ints[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
            ? std::vector<int> vint(ints, ints + array_size(ints));
            ?
            ? std::string strs[] = { "Amy", "Ralph", "Simon", "Maggie" };
            ? std::vector<std::string> vstr(strs, strs + array_size(strs));
            ?
            ? std::for_each(vint.begin(), vint.end(), std::cout << _1 << " ");
            ? std::cout << std::endl;
            ? std::for_each(vstr.begin(), vstr.end(), std::cout << _1 << " ");

            輸出:

            2 3 5 7 11 13 17 19 23
            Amy Ralph Simon Maggie

            順便說一下,在 boost.type_traits 里面有一個類似于 ArraySize 的工具,叫做 extent ,它更加強大,可以對付多維數(shù)組,不過是否值得為了這個而把 boost.type_traits 包含到工程里面去就看讀者自己抉擇了。

            =================================================================================

            容器的初始化是如此的常見,以至于 boost 提供了一個 assign 庫來簡化這些操作。boost.assign 大量利用了重載的逗號和括號來簡化賦值操作,提供了甚至比用數(shù)組更加簡潔的語法:

            #include <iostream>
            #include <algorithm>
            #include <vector>
            #include <string>

            #include <boost/assign/std/vector.hpp>
            #include <boost/assign/std/list.hpp>

            using namespace boost::assign;

            int main()
            {
            ? std::vector<int> vint;
            ? vint += 2,3,5,7,11,13,17,19,23;
            ?
            ? std::vector<std::string> vstr;
            ? vstr += "Amy","Ralph","Simon","Maggie";
            ?
            ? std::list<std::string> lstr;
            ? lstr += "Amy","Ralph","Simon","Maggie";
            ???
            ? std::for_each(vint.begin(), vint.end(), std::cout << _1 << " ");
            ? std::cout << std::endl;
            ? std::for_each(vstr.begin(), vstr.end(), std::cout << _1 << " ");
            ? std::cout << std::endl;
            ? std::for_each(lstr.begin(), lstr.end(), std::cout << _1 << " ");
            }


            運行這個程序,輸出與前面的大致相同,但是我們注意到初始化更加簡潔了,而且也不需要額外的空間來存儲數(shù)組,對于各種類型,都能夠以統(tǒng)一的方式來初始化,真是妙不可言。有趣的是 assign 的作者在文檔中還特意引用了 Bjarne Stroustrup 的話作為引子:

            There appear to be few practical uses of operator,().
            Bjarne Stroustrup, The Design and Evolution of C++

            這也許就是 C++ 最大的魅力之一:你無法預(yù)料它可以辦到些什么。

            下面關(guān)于 map 的例子也使用 boost.assign ,可以看到重載的括號給我們帶來了多少方便。

            #include <iostream>
            #include <algorithm>
            #include <map>
            #include <string>

            #include <boost/lambda/lambda.hpp>
            #include <boost/lambda/bind.hpp>

            #include <boost/assign/list_inserter.hpp>
            #include <boost/assign/list_of.hpp>

            using namespace std;
            using namespace boost::assign;
            using namespace boost::lambda;

            int main()
            {
            ? map<string,int> months;?
            ?
            ? insert( months )
            ??? ( "january",?? 31 )( "february", 28 )
            ??? ( "march",???? 31 )( "april",??? 30 )
            ??? ( "may",?????? 31 )( "june",???? 30 )
            ??? ( "july",????? 31 )( "august",?? 31 )
            ??? ( "september", 30 )( "october",? 31 )
            ??? ( "november",? 30 )( "december", 31 );
            ???
            ? map<int,string> persons = map_list_of
            ??? (2,"Amy")(3,"Ralph")
            ??? (5,"Simon")(7,"Maggie");
            ???
            ? for_each( months.begin(), months.end(),
            ??? cout << bind(&map<string,int>::value_type::second, _1) << "\t"
            ???????? << bind(&map<string,int>::value_type::first, _1) << "\n"
            ? );
            ? cout << endl;
            ? for_each( persons.begin(), persons.end(),
            ??? cout << bind(&map<int,string>::value_type::first, _1) << "\t"
            ???????? << bind(&map<int,string>::value_type::second, _1) << "\n"
            ? );?
            }

            輸出:

            30????? april
            31????? august
            31????? december
            28????? february
            31????? january
            31????? july
            30????? june
            31????? march
            31????? may
            30????? november
            31????? october
            30????? september

            2?????? Amy
            3?????? Ralph
            5?????? Simon
            7?????? Maggie

            posted on 2006-06-28 13:45 笑笑生 閱讀(149) 評論(0)  編輯 收藏 引用

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


             
            Copyright © 笑笑生 Powered by: 博客園 模板提供:滬江博客
            人妻中文久久久久| 精品久久久久久成人AV| 欧美粉嫩小泬久久久久久久 | 久久久久九九精品影院| 国产精品无码久久久久| 亚洲伊人久久成综合人影院 | 无遮挡粉嫩小泬久久久久久久| 蜜臀av性久久久久蜜臀aⅴ麻豆| 青青青国产精品国产精品久久久久| 久久精品无码免费不卡| 无码专区久久综合久中文字幕| 久久中文字幕一区二区| 久久久久se色偷偷亚洲精品av| 久久久青草青青亚洲国产免观| 久久精品国产亚洲AV蜜臀色欲| 99久久99久久精品国产| 久久丫精品国产亚洲av| 亚洲AⅤ优女AV综合久久久| 狠狠色丁香久久婷婷综| 亚洲中文字幕无码一久久区| 久久久久成人精品无码| 伊人久久大香线蕉精品| AV狠狠色丁香婷婷综合久久 | 成人久久免费网站| 狠狠色丁香婷婷久久综合 | 久久乐国产综合亚洲精品| 99热精品久久只有精品| 91精品国产色综合久久| 天堂久久天堂AV色综合| 2020国产成人久久精品| 久久伊人中文无码| 欧美激情精品久久久久久| 国产成人香蕉久久久久| 国产成人精品久久亚洲高清不卡 | 久久精品人成免费| 99国产精品久久久久久久成人热| 性高湖久久久久久久久| 久久综合给久久狠狠97色| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 久久超碰97人人做人人爱| 色欲久久久天天天综合网|