• <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>
            隨筆-90  評論-947  文章-0  trackbacks-0

            打算先把基礎的東西組織起來,作為一個“大庫”(見上一篇《小庫還是大庫?》)。然后填加各個實用功能,作為一個個小庫或者大庫,過段時間再想辦法組織整理了。

            首先是類型系統,我想來想去,覺得還是必須整理一下,尤其是 unsigned XXX 寫起來太難看了,可是這又帶來了問題——WinDef.h 把好聽的名字都占去了。然后,我只能在自己的命名空間下這樣來一番了:

            xlDef.h
            #ifndef __XLDEF_H_44FDC6C3_12F1_4BF3_8F9F_1ABED755E8ED_INCLUDED__
            #define __XLDEF_H_44FDC6C3_12F1_4BF3_8F9F_1ABED755E8ED_INCLUDED__


            namespace xl
            {
               
            typedef char CHAR;
               
            typedef unsigned char UCHAR;
               
            typedef short SHORT;
               
            typedef unsigned short USHORT;
               
            typedef int INT;
               
            typedef unsigned int UINT;
               
            typedef long LONG;
               
            typedef unsigned long ULONG;
               
            typedef long long LONGLONG;
               
            typedef unsigned long long ULONGLONG;

               
            typedef void VOID;
               
            typedef bool BOOLEAN;
               
            typedef INT BOOL;

               
            typedef UCHAR BYTE;
               
            typedef USHORT WORD;
               
            typedef ULONG DWORD;
               
            typedef ULONGLONG QWORD;

               
            const BOOL TRUE = 1;
               
            const BOOL FALSE = 0;
               
            const VOID *NULL = 0;

               
            typedef struct interface;

            }
            // namespace xl


            #endif // #ifndef __XLDEF_H_44FDC6C3_12F1_4BF3_8F9F_1ABED755E8ED_INCLUDED__

            但是,問題是,當 using namespace xl 并 #include <Windows.h> 以后,隨手寫一個“DWORD”,就會有歧義了。如果用的時候要寫成 xl::DWORD,那還不如現在就命名成 XL_DWORD 好了……這點仍然在糾結中……路過朋友請給點意見:)

            接下來是最基礎一層的組成。我想先把 Array、List、BinaryTree 給實現一下。然后第二層中利用 Array 實現 String,利用 List 搞個 Queue、Stack 什么的,利用 BinaryTree 搞個 Map、Set 之類的。只是數據結構中的“圖”,不知道怎么搞比較方便,如果可能,也可以在第一層實現掉。

            不得不考慮的是 iterator 的問題。由于 STL 的 iterator 深入人心,我很想也搞個類似的支持。但是,STL 的 iterator 是可以跨容器的,也就是,可以在 list 的 insert 里填入 vector 的 iterator 作為參數。我不太了解 STL 的具體做法,但是粗看似乎是用模板實現的。可是這樣的話,就有一個很大的問題,這個模板參數將是沒有任何約束的,在明明需要 iterator 的參數的位置,我可以隨意填一個別的東西,直到有調用 iterator 的什么方法,編譯器才給出錯誤。這樣,實際上在接口中沒法為使用者提供足夠的信息(或者說,提供語法上的約束)讓他明白這個參數應該是什么。比較好的做法可能是 .Net 的那一套,定義接口 IEnumerator、IEnumerable 等等,然后各個類都去實現這個接口,迭代器也可以只針對接口編寫。但是由于 C++ 中的多態必須用指針表示,那么在參數、返回值(特別是返回值)中,指針的 delete 又給使用帶來了麻煩。于是,似乎需要先有一個完善的智能指針作為基礎才可以。而智能指針,如果要線程安全,又必須有平臺支持,所以似乎智能指針沒法放在這么基礎的位置。…………

            繞了好久,也想了好久,始終還是找不到好的辦法。所以,我暫時覺得還是放棄跨容器的 iterator 了,其實說到底,這只是勉強制造的、看似來很精巧、其實不那么完美的東西而已。

            Array、List、Tree 暫時設計如下:

            xlArray.h
            #ifndef __XLARRAY_H_3B18D7E2_B52A_4D57_BE4B_657F9D17320D_INCLUDED__
            #define __XLARRAY_H_3B18D7E2_B52A_4D57_BE4B_657F9D17320D_INCLUDED__


            #include "xlDef.h"

            namespace xl
            {

               
            template <typename T>
               
            class Array
               
            {
               
            public:
                   
            Array();
                   
            Array(const Array<T> &that);
                    ~
            Array();

               
            public:
                   
            class Iterator
                   
            {
                   
            public:
                       
            Iterator();
                       
            Iterator(const Array<T> *array);
                       
            Iterator(Iterator &that);

                   
            private:
                       
            array<T> *array;
                       
            UINT current;
                       
            BOOLEAN bof;
                       
            BOOLEAN eof;

                   
            public:
                       
            T &operator * ();
                       
            T *operator -> ();

                   
            public:
                       
            Iterator &operator = (Iterator &that);
                       
            BOOLEAN operator == (Iterator &that);
                       
            BOOLEAN operator != (Iterator &that);

                   
            public:
                       
            Iterator operator ++ ();
                       
            Iterator operator ++ (int);
                       
            Iterator operator -- ();
                       
            Iterator operator -- (int);
                    };

               
            public:
                   
            Iterator Bof();
                   
            Iterator Begin();
                   
            Iterator End();
                   
            Iterator Eof();

               
            public:
                   
            Array<T> &operator=(const Array<T> &that);
                   
            BOOLEAN operator==(const Array<T> &that) const;
                   
            BOOLEAN operator!=(const Array<T> &that) const;

               
            public:
                   
            T &operator[](UINT index);
                   
            const T &operator[](UINT index) const;

               
            public:
                   
            BOOLEAN Empty();
                   
            UINT Count();

               
            public:
                   
            VOID PushFront(const T &tValue);
                   
            VOID PushBack(const T &tValue);
                   
            VOID PopFront();
                   
            VOID PopBack();
                   
            VOID Insert(const Iterator &beforeWhich, const T &value);
                   
            VOID Insert(const Iterator &beforeWhich, const Iterator &firstToInsert, const Iterator &NextOfLastToInsert);
                   
            Iterator Delete(const Iterator &which);
                   
            Iterator Delete(const Iterator &firstToDelete, const Iterator &nextOfLastToDelete);
                   
            VOID SetValue(const Iterator &which, const T &value);
                   
            VOID SetValue(const Iterator &firstToDelete, const Iterator &nextOfLastToDelete, const T &value);

               
            private:
                   
            T *m_pData;
                };

            }
            // namespace xl

            #endif // #ifndef __XLARRAY_H_3B18D7E2_B52A_4D57_BE4B_657F9D17320D_INCLUDED__

             

            xlList.h
            #ifndef __XLLIST_H_2BEF1B3C_A056_4EC7_B5E3_9898E7945B54_INCLUDED__
            #define __XLLIST_H_2BEF1B3C_A056_4EC7_B5E3_9898E7945B54_INCLUDED__


            #include "xlDef.h"

            namespace xl
            {
               
            template <typename T>
               
            class List
               
            {
               
            public:
                   
            List();
                   
            List(const List<T> &that);
                    ~
            List();

               
            private:
                   
            struct Node
                   
            {
                       
            T value;
                       
            Node *prev;
                       
            Node *next;
                    };

               
            public:
                   
            class Iterator
                   
            {
                   
            public:
                       
            Iterator();
                       
            Iterator(const List<T> *list);
                       
            Iterator(Iterator &that);

                   
            private:
                       
            List<T> *list;
                       
            Node *current;
                       
            BOOLEAN bof;
                       
            BOOLEAN eof;

                   
            public:
                       
            T &operator * ();
                       
            T *operator -> ();

                   
            public:
                       
            Iterator &operator = (Iterator &that);
                       
            BOOLEAN operator == (Iterator &that);
                       
            BOOLEAN operator != (Iterator &that);

                   
            public:
                       
            Iterator operator ++ ();
                       
            Iterator operator ++ (int);
                       
            Iterator operator -- ();
                       
            Iterator operator -- (int);
                    };

               
            public:
                   
            Iterator Bof();
                   
            Iterator Begin();
                   
            Iterator End();
                   
            Iterator Eof();

               
            public:
                   
            List<T> &operator=(const List<T> &that);
                   
            BOOLEAN operator==(const List<T> &that) const;
                   
            BOOLEAN operator!=(const List<T> &that) const;

               
            public:
                   
            BOOLEAN Empty();
                   
            UINT Count();

               
            public:
                   
            VOID PushFront(const T &tValue);
                   
            VOID PushBack(const T &tValue);
                   
            VOID PopFront();
                   
            VOID PopBack();
                   
            VOID Insert(const Iterator &beforeWhich, const T &value);
                   
            VOID Insert(const Iterator &beforeWhich,
            const Iterator &firstToInsert, const Iterator &NextOfLastToInsert);
                   
            Iterator Delete(const Iterator &which);
                   
            Iterator Delete(const Iterator &firstToDelete,
            const Iterator &nextOfLastToDelete);

               
            public:
                   
            Node *head;
                   
            Node *tail;
                };

            }
            // namespace xl

            #endif // #ifndef __XLLIST_H_2BEF1B3C_A056_4EC7_B5E3_9898E7945B54_INCLUDED__

             

            xlTree.h
            #ifndef __XLTREE_H_6BB48AA6_133A_4E9F_944E_504B887B6980_INCLUDED__
            #define __XLTREE_H_6BB48AA6_133A_4E9F_944E_504B887B6980_INCLUDED__


            #include "xlDef.h"

            namespace xl
            {
               
            template <typename T>
               
            class Tree
               
            {
               
            public:
                   
            Tree();
                   
            Tree(const Tree<T> &that);
                    ~
            Tree();

               
            private:
                   
            struct Node
                   
            {
                       
            T value;
                       
            Node *parent;
                       
            Node *left;
                       
            Node *right;
                    };

               
            private:
                   
            class Iterator
                   
            {
                   
            public:
                       
            Iterator();
                       
            Iterator(const Tree<T> *tree);
                       
            Iterator(Iterator &that);

                   
            private:
                       
            Tree<T> *tree;
                       
            Node *current;
                       
            BOOLEAN bof;
                       
            BOOLEAN eof;

                   
            public:
                       
            T &operator * ();
                       
            T *operator -> ();

                   
            public:
                       
            Iterator &operator = (Iterator &that);
                       
            BOOLEAN operator == (Iterator &that);
                       
            BOOLEAN operator != (Iterator &that);

                   
            public:
                       
            Iterator Parent();
                       
            Iterator Left();
                       
            Iterator Right();
                    };

                   
            class PreorderIterator : public Iterator
                   
            {
                   
            public:
                       
            Iterator operator ++ ();
                       
            Iterator operator ++ (int);
                       
            Iterator operator -- ();
                       
            Iterator operator -- (int);
                    };

                   
            class InorderIterator : public Iterator
                   
            {
                   
            public:
                       
            Iterator operator ++ ();
                       
            Iterator operator ++ (int);
                       
            Iterator operator -- ();
                       
            Iterator operator -- (int);
                    };

                   
            class PostorderIterator : public Iterator
                   
            {
                   
            public:
                       
            Iterator operator ++ ();
                       
            Iterator operator ++ (int);
                       
            Iterator operator -- ();
                       
            Iterator operator -- (int);
                    };

               
            public:
                   
            Iterator Bof();
                   
            Iterator Begin();
                    Iterator Eof();

               
            public:
                   
            Tree<T> &operator=(const Tree<T> &that);
                   
            BOOLEAN operator==(const Tree<T> &that) const;
                   
            BOOLEAN operator!=(const Tree<T> &that) const;

               
            public:
                   
            BOOLEAN Empty();
                   
            UINT Count();

               
            public:
                    VOID InsertLeft(const Iterator &beforeWhich, const T &value);
                   
            VOID InsertRight(const Iterator &beforeWhich, const T &value );
                   
            Iterator Delete(const Iterator &which);

               
            public:
                   
            Node *head;
                };

            }
            // namespace xl

            #endif // #ifndef __XLTREE_H_6BB48AA6_133A_4E9F_944E_504B887B6980_INCLUDED__

            (Tree 的接口還沒完全考慮好,也不知道有沒有必要把 Node 獨立出來。)

            這樣是否大概足夠了?敬請大家指教~

            (再次重申一下,請不要來留個言說“干嗎要重新發明輪子?”、“XXX 不是很好用嗎?”之類的,謝謝!歡迎志同道合的朋友探討,如能為我解惑,那么非常感謝。)

            posted on 2009-09-26 17:43 溪流 閱讀(664) 評論(18)  編輯 收藏 引用 所屬分類: C++

            評論:
            # re: 開始把庫搞起來了 2009-09-27 12:46 | 陳梓瀚(vczh)
            碰巧我也再造輪子。我吸取了stl和.net的經驗做了一套collection出來,linq也實現了,string也實現了。現在正在做stream,還有無縫支持自定義的用戶類型。這就有4套子系統了,其中自反連接和兩兩互轉一共需要15個運算器(包括regex啦,linq啦,自定義語法分析器什么的)。

            因為我是做編譯器的所以對復雜數據結構的靈活運算要求非常高,但是效率并沒有太苛求。完了我們可以交流一下。  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 12:55 | 陳梓瀚(vczh)
            然后我跟你說說VL++2.0的一些故事……現在已經推翻掉寫3.0了,其中的一些決定就是
            1:不再typedef基礎類型
            2:不再加前綴
            3:大規模利用模板
            4:加強各個模塊之間的關系,互操作性要變得很強

            你可以考慮不走我的老路……  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 12:58 | 陳梓瀚(vczh)
            于是最后提示一點,根據我前面幾年造輪子的實踐,獨立二叉樹的接口一點意義都沒有……  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 15:49 | 溪流
            @陳梓瀚(vczh)

            陳老師你好,我一年多前實習的時候因為公司不允許使用STL、MFC等等所有流行的庫,叫我們“用到的數據結構自己寫”。當時只寫了個 Vector、String,足以應付任務了。不過我就是從那時開始明白寫庫的意義,以及感受到用自己的庫的那種爽快的感覺的。

            很佩服你的技術,粗看過你的代碼,我知道你把基礎數據結構全部實現了一遍,甚至regex,以及在代碼里寫 EBNF,等等。(我第一篇日志的開頭語不知道您看過了沒,呵呵)

            我也想不走老路,不過有些東西可能不走一遍不會明白,所以我想可能先自然一點,到第二遍、第三遍再來總結以及回避已知問題。關于你說的4點,我比較想了解原因以及大概做法,可否稍微解釋下?特別是1和2,這個是現在就擺在我面前的。然后是3、4,我可以聽一聽,雖然可能不是馬上體會得到。  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 15:51 | 溪流
            @陳梓瀚(vczh)

            你的意思是說 Tree::Node 沒必要暴露出來嗎?再問一下問一下,你覺得基礎庫里有必要存在二叉樹這種結構嗎?還有沒有必要以及可能包含圖的結構呢?  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 18:00 | OwnWaterloo
            @溪流
            1. 如非必要,不typedef基礎類型

            為什么要typedef?
            typedef是為了提供語意。

            DWORD, WORD, BYTE的語意是固定長度整數。
            stdint.h, cstdint, sys/stdin.h, windows.h 中已經有這樣的功能, 就盡可能去復用。
            自己省事 —— 你有精力去為不同平臺定義出對應的DWORD, WORD, BYTE嗎?
            既然上面的幾個文件中已經給出了這種功能, 并且在各個平臺下都測試過, 為什么不直接使用呢?

            別人也省事。
            需要明白一點:用戶與其依賴的庫通常不是線性結構,而是樹形結構。
            A庫為了可移植性的去typedef DWORD, WORD, BYTE,
            B庫也為了可移植性去typedef DWORD, WORD, BYTE,
            一個客戶C, 同時需要A、B, 他該用哪個庫的DWORD?
            這種作法是徒增不必要的概念。


            對自己庫獨有, 并有可能改變的概念, 才可以考慮使用typedef 來建立一個語意。
            比如time.h中的time_t, clock_t, 代表了兩個獨立的概念。
              回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 18:10 | OwnWaterloo
            @溪流
            2:不再加前綴

            其實vczh同學放出來的代碼中的VL_前綴……
            我覺得看上去是很傷眼的……
            當然, 這是口味問題。


            關于這個問題:
            "但是,問題是,當 using namespace xl 并 #include <Windows.h> 以后,隨手寫一個“DWORD”,就會有歧義了。如果用的時候要寫成 xl::DWORD,那還不如現在就命名成 XL_DWORD 好了"

            首先, 不必定義xl::DWORD。
            對于其他情況, 名字空間相對于前綴是有一些優勢的。
            1. 如果存在歧義, 無論是名字空間,還是前綴, 都必須使用全稱。
            2. 不存在歧義的時候, 名字空間可以打開, 可以別名。 而前綴必須時刻都帶著, 永遠逃不掉。
            3. 如果不小心, 兩個使用前綴的庫都出現了相同名字, 前綴技術就很麻煩。
            A庫是個做網絡的, 有一個 net_f,
            B庫也是個做網絡的, 依然一個 net_f,
            要同時使用兩個庫, 就需要自己去寫轉發函數。

            而名字空間, 可以一開始就很長。
            namespace net_byA { void f() }
            namespace net_byB { void f() }


            只使用A(或B)的用戶,就可以使用別名:
            namepsace net = net_byA(B);
            net::f;

            如果同時使用A、B的用戶, 只好:
            net_byA::f;
            net_byB::f;

            也比自己寫轉發函數要強。

            總之, 名字空間是一種更靈活的方式。

            如果決定使用C++編寫庫, 而且不考慮過分古董的編譯器, 就應該選用名字空間。  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 18:26 | OwnWaterloo
            @溪流

            各種現有的流行的庫中, 實現了侵入式容器的比較少。
            大都是非侵入式容器。

            侵入式容器我只在如下一些庫中見到過:
            linux/list.h, linux/rbtree.h
            sourceforge有個叫libaasdl的項目,有一個GDST(generic data-structure template)子庫中的一些是侵入式的(還有一些我沒看完)

            SGI-STL中4種關聯容器底層使用的是同一種容器,_Rb_tree。
            它是非侵入式的。
            但是構建它的_Rb_tree_base、_Rb_tree_base_iterator都是非侵入式的。
            SGI-STL沒有構建出一個侵入式的RbTree層, 而是直接使用侵入式的_Rb_tree_base,和_Rb_tree_base_iterator構建出了非侵入式的_Rb_tree。
            稍微有點可惜。
            不過即使有一個侵入式的RbTree, SGI-STL也是不會將其公開出來的。


            如果想練手, 可以考慮構建一套侵入式的容器, 比僅僅重復STL中的東西來得有意義。

            還有, STL中沒有樹式的堆。
            heap相關的那幾個函數都是對random_access的線性表使用的。
            也可以考慮在這里做做文章。  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 18:51 | OwnWaterloo
            const VOID *NULL = 0;
            在C++中, 這樣定義NULL是行不通的。
             
            普遍的做法是直接使用0,或者stddef.h, cstddef 中的NULL宏:
            #ifdef __cplusplus
            #define NULL 0
            #else
            #define NULL ((void*)0) /* 這是C中的做法 */
            #endif
             
            void* 在C中可以隱式轉換到其他類型指針。
            但C++不行。
             
             
            或者, 更激進一點, 使用nullptr:
            nullptr
            因為C++0x將引入nullptr作為關鍵字。
            使用nullptr,算是"向前兼容"吧…… 等轉到C++0x時,就可以直接使用真正的nullptr了。
             
            上面最后一種nullptr和C++0x中的語意最相似, 不過不一定能在所有編譯器中都通過。
            至少要支持成員函數模板才行。
            如果不支持匿名類可以改用別的方式實現。
             
             
             
             typedef struct interface;
            這是什么語法?
            這也是徒增概念的地方。
             
            C++程序員如果不知道下面的代碼是一個interface
            struct Ixxx {
                virtual ~Ixxx();
                virtual ...
            };
             
            將struct 換成interface對他的幫助也不大。
              回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 19:10 | OwnWaterloo
            不叫"跨容器"的iterator。
            而是iterator符合特定的concepts。
            不過你說對了, 它確實和模板有關。
             
            比如,使用一對forwarding_iterator構造vector的偽代碼:
            concepts
             
            vector有一個構造函數模板。
            只要FotIt 滿足forwarding_iterator的概念,上面的構造函數就可以生成。
            forwarding_iterator 要支持(但不限于)++, *, 因為上面的代碼使用了這2個操作符。
            vector的實現也不會是上面那樣, 不會調用new 去默認構造一次。
            會使用其allocator來分配,并使用uninitialized_copy。
            不過那樣就看不到vector() 對forwarding_iterator的要求了。
             
             
            這是C++中的方式,GP的,基于concepts的方式。C#中可是沒得這么爽的哦。
            并且, GP的、基于concepts的方式, 也可以退化成OOP的,基于interface的方式。
            反之不行, 因為concepts的偶和性更低。
             
             
            不僅僅是容器。 整個STL中的組件都是通過concepts來協作而非interface。
            如果你喜歡struct Iterator的方式, 或者IComparable , 也可以這么搞一套。
            代碼不會比GP來得少, 效率不會比GP來得高, 也不會比GP靈活 —— GP可以退化為基于interface, 反之不行。
             
              回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 19:10 | OwnWaterloo
            上面貼的代碼有問題, 重新貼一下……
             
            template<typename T,  >
            class vector {
                T
            * first_;
                T
            * last_;
            public:
                template
            <class ForIt>
                vector(ForIt first,ForIt last) {
                    difference_type d 
            = distance(first,last);
                    first_ 
            = new T[ d + padding ];
                    last_ 
            = first_ + d;
                    
            for (T* p = first;first!=last;++first,++p)
                        
            *= *first;
                }
            };
              回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 20:33 | 溪流
            @OwnWaterloo

            先謝過您的這么詳細的指點。等我仔細看過后再來提后續問題:)  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 22:35 | 溪流
            @OwnWaterloo

            1、關于 typedef

            第一,我想我要寫的庫要保持獨立性。如果去包含了 Winows.h 了,那么就失去了這一部分的獨立性了。在做容器方面的東西的時候,實際上我根本不會用到 Windwos API,而這一 include,增加無畏的依賴的同時,還把平臺陷死了(雖然我不準備搞多么跨平臺的東西,但是明明可以不依賴的,還是不要去依賴,是嗎?)

            我想,庫的用戶可能不需要去寫太多次 a::DWORD、b::DWORD,只要他們的定義是兼容的,傳入的值就可以用。

            其實我最頭痛的就是 Windows.h 把這些名字都占去了,而且是全局的,是的用戶無法簡單地寫一個 DWORD 來定義 Windows.h 中的 DWORD 了。我知道加前綴不是好的解決方案,可是還有其他一套如此通用的名字嗎?
              回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 22:45 | OwnWaterloo
            @溪流
            用stdint.h。 把這個棘手的工作交給編譯器提供商。
            并且, 你實現容器庫的時候, 需要DWORD么……


            > 只要他們的定義是兼容的,傳入的值就可以用。
            你要去檢查。 是否每個庫都是兼容的。

            另一種方式是只依賴于一處定義。比如stdint.h


            msvc沒有提供stdint.h, 因為它不支持C99。
            網上有一個stdint.h for msvc, 使用BSD3條款的許可證。

            或者自己寫:

            msvc 提供了 __intN擴展。
            所以 intN_t uintN_t 很好處理
            int_leastN_t, 這個本來就不能假設它的寬度, 按字面來即可。

            uintptr_t, intptr_t 可以包含basetsd.h
            typedef INT_PTR intptr_t;
            typedef UINT_PTR uintptr_t;


            現在你代碼中依賴的就是:
            (u)intN_t, (u)int_fastN_t ,, (u)intptr_t, (u)intmax_t 等等。  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-27 23:58 | 溪流
            @OwnWaterloo

            是的,現在是用不著 DWORD,但是以后一些功能庫會用到。
            stdint.h 中的類型名稱似乎也不怎么干凈利索。
            要不就直接用標準名稱好了?只是我很不喜歡 unsigned int, size_t 這種寫法。  回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-28 00:17 | OwnWaterloo
            @溪流
            這個…… 其實是個口味問題 …… all fine.
            我比較懶…… 有現成的就喜歡用現成的…… so ……

              回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-28 00:27 | 溪流
            @OwnWaterloo

            打算這樣,如何?

            namespace xl
            {
                typedef unsigned 
            char uchar;
                typedef unsigned 
            short ushort;
                typedef unsigned 
            int uint;
                typedef unsigned 
            long ulong;
                typedef 
            long long longlong;
                typedef unsigned 
            long long ulonglong;

                typedef wchar_t wchar;
                typedef unsigned wchar uwchar;

                typedef __int8 int8;
                typedef __int16 int16;
                typedef __int32 int32;
                typedef __int64 int64;

                typedef unsigned int8 uint8;
                typedef unsigned int16 uint16;
                typedef unsigned int32 uint32;
                typedef unsigned int64 uint64;

                
            struct
                
            {
                    template
            <typename T>
                    
            operator T*() const
                    
            {
                        
            return 0;
                    }


                }
             nullptr;

            }
             // namespace xl


            我的目的主要是為了書寫簡潔,其他的其實對我來說關系不大,暫時主要考慮 Win + MSVC 平臺。nullptr 的定義真的好精妙!
              回復  更多評論
              
            # re: 開始把庫搞起來了 2009-09-28 00:40 | OwnWaterloo
            @溪流
            nullptr是《eff cpp》中提到的。

            對于int和指針的重載:
            void f(int );
            void f(void* );

            f(0); // f(int );
            f(NULL); // 如果是stddef.h 中的NULL, f(int );
            f(nullptr); // 書中提到的那個nullptr, 會選中 f(void* );

            如果還有另一種指針:

            void f(int* ); nullptr 會引起歧義。

            當然, 最好是避免這種重載……

              回復  更多評論
              
            中文字幕无码久久久| 国产99久久九九精品无码| 久久93精品国产91久久综合| 久久亚洲av无码精品浪潮| 色偷偷888欧美精品久久久| 久久综合久久久| 久久91精品综合国产首页| 久久久久亚洲AV无码专区网站 | 国产一区二区精品久久| 久久99国产综合精品女同| 久久精品国产亚洲欧美| 久久久久免费视频| 久久这里只有精品首页| 久久久噜噜噜久久| 欧美一级久久久久久久大| 久久久久波多野结衣高潮| 久久精品视频网| 亚洲欧洲精品成人久久曰影片| 久久国产精品一国产精品金尊| 色综合久久天天综线观看| 久久婷婷五月综合国产尤物app| 久久精品国产精品亚洲精品| 久久久www免费人成精品| 国产激情久久久久影院老熟女| 人妻少妇久久中文字幕| 久久久久综合网久久| 少妇无套内谢久久久久| 91久久香蕉国产熟女线看| 亚洲午夜久久久久久久久电影网| 色综合合久久天天给综看| 精品久久久久久国产| 伊人久久无码中文字幕| 狠狠久久综合伊人不卡| 久久精品国产亚洲AV高清热| 午夜精品久久久久久久| 无码任你躁久久久久久| 精品国产91久久久久久久a | 亚洲综合日韩久久成人AV| 香港aa三级久久三级老师2021国产三级精品三级在 | 奇米影视7777久久精品人人爽| 久久精品无码一区二区三区日韩 |