• <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>
            posts - 13, comments - 4, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            Exceptional C++ Style 讀書筆記(三)

            Posted on 2008-11-06 23:30 Batiliu 閱讀(376) 評論(0)  編輯 收藏 引用 所屬分類: 讀書筆記

            第三十二條 奇形怪狀

            下面程序的輸出是什么?

            #include <iostream>
             
            int _tmain(int argc, _TCHAR* argv[])
            {
                int x = 1;
             
                // 下面這行代碼你確認在遞增嗎??/
                ++x;
             
                std::cout << x << std::endl;
             
                return 0;
            }

            “輸出 2”,如果你無須思索的回答道。那么,恭喜你。。。。答錯了。不相信?請你將這段程序一字不差的復制到Visual Studio中(本人環境VS2008),然后Ctrl+F5,正確答案會立即顯示在眼前:輸出居然是 1!

             

            最好在你親自試驗了后,我們來一起揭曉原因:

            注意到“// 下面這行代碼你確認是遞增嗎??/”這行注釋了嗎?注釋中結尾的“??/”會被轉換成“\”,而后者放在一行的末尾作用相當于將接下來的一行“粘貼”到這一行的末尾!這太令人詫異了!本例中,它將接下來的“++x”粘貼到了注釋行的末尾,這樣“++x”就成了注釋的一部分,不會被實際實行了。

            為什么會這樣?因為C++從C語言繼承了一個“三字符組”的特性。所謂三字符組(trigraph)是指三個字符組成的轉義符,比如“??/”=“\”,“??!”=“~”等。

             

            風格案例研究

             

            以下代碼展示了在已有容器中創建索引表的一種慣用法。

            // 代碼展示:索引表
            #include <vector>
            #include <map>
            #include <algorithm>
             
            // Solution1
             
            namespace Solution1 {
                template<class Iter>
                class sort_idxtbl_pair {
                public:
                    void set(const Iter& it, int i) { it_ = it; i_ = i; }
                    bool operator<(const sort_idxtbl_pair& other) const
                    { return *it_ < *other.it_; }
                    operator int() const { return i_; }
                private:
                    Iter it_;
                    int i_;
                };
             
                template<class IterIn, class IterOut>
                void sort_idxtbl(IterIn first, IterIn last, IterOut out) {
                    std::vector<sort_idxtbl_pair<IterIn> > v(last - first);
                    
                    for (int i = 0; i < last - first; ++i)
                        v[i].set(first + i, i);
             
                    std::sort(v.begin(), v.end());
             
                    std::copy(v.begin(), v.end(), out);
                }
            }
             
            // Solution2:使用std::pair而不是重新發明一個類似pair的輔助類。
            namespace Solution2 {
                template<class T, class U>
                struct ComparePair1stDeref {
                    bool operator()(const std::pair<T,U>& a, const std::pair<T,U>& b) const
                    { return *a.first < *b.first; }
                };
             
                template<class IterIn, class IterOut>
                void sort_idxtbl(IterIn first, IterIn last, IterOut out) {
                    std::vector<std::pair<IterIn, int> > s(last - first);
                    for (int i = 0; i < s.size(); ++i)
                        s[i] = std::make_pair(first + i, i);
             
                    std::sort(s.begin(), s.end(), ComparePair1stDeref<IterIn,int>());
             
                    for (int i = 0; i < s.size(); ++i, ++out)
                        *out = s[i].second;
                }
            }

            測試用例:

            #include <iostream>
             
            int _tmain(int argc, _TCHAR* argv[])
            {
                int a[10] = {8, 9, 1, 3, 5, 7, 6, 4, 2, 0};
                std::vector<int> idxtbl(10);
             
                Solution2::sort_idxtbl(a, a + 10, idxtbl.begin());
             
                for (int i = 0; i < 10; ++i)
                    std::cout << "i = " << i 
                            << ", idxtbl[i] = " << idxtbl[i]
                            << ", a[idxtbl[i]] = " << a[idxtbl[i]]
                            << std::endl;
             
                return 0;
            }

            以下代碼展示了一個用于外覆回調函數的慣用手法。

            class CallbackBase {
            public:
                virtual void operator()() const {};
                virtual ~CallbackBase() = 0;
            };
             
            CallbackBase::~CallbackBase() {}
             
            template<typename T>
            class Callback : public CallbackBase {
            public:
                typedef void (T::*F)();
             
                Callback(T& t, F t) : t_(&t), f_(f) {}
                void operator()() const { (t_->*f_)(); }
             
            private:
                T* t_;
                F  f_;
            };
             
            template<typename T>
            Callback<T> make_callback(T& t, void(T::*f)()) {
                return Callback<t>(t, f);
            }
             
            你需要支持const成員函數?支持非void類型的返回值?支持不同參數類型或數目的回調函數?別急、別急,敬請期待我即將發布的《基于C++的多播委托》,如果你實在等不及,Loki庫的'functors'將為你帶來頂級大師的盛宴。
             
            久久精品无码一区二区三区日韩| 少妇无套内谢久久久久| 青青草原综合久久大伊人精品| 久久精品国产半推半就| 热综合一本伊人久久精品| 少妇精品久久久一区二区三区 | 国产福利电影一区二区三区久久老子无码午夜伦不 | 色欲综合久久中文字幕网| 91精品国产91久久久久久蜜臀| 久久亚洲av无码精品浪潮| 久久精品国产久精国产一老狼| 国内精品久久久久影院一蜜桃 | 99久久成人国产精品免费| 欧美午夜A∨大片久久| 久久综合九色综合精品| 中文字幕无码免费久久| 亚洲国产天堂久久综合| 国产农村妇女毛片精品久久 | 亚洲国产日韩欧美综合久久| 久久综合九色综合久99| 熟妇人妻久久中文字幕| 久久久久亚洲av综合波多野结衣| 9999国产精品欧美久久久久久| 久久精品亚洲精品国产色婷| 久久人人爽人人爽人人片av麻烦| 久久亚洲AV无码西西人体| 久久国产高清一区二区三区| 伊人久久精品线影院| 久久精品中文字幕久久| 精品久久久久久国产91| 久久久久久免费一区二区三区| 久久久久久亚洲Av无码精品专口| 久久精品国产久精国产果冻传媒| 久久综合视频网| 久久婷婷五月综合97色直播| 久久久久免费精品国产| 东方aⅴ免费观看久久av| 蜜臀av性久久久久蜜臀aⅴ| 国产综合精品久久亚洲| 久久国产免费| 亚洲乱码中文字幕久久孕妇黑人|