• <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>

            陳碩的Blog

            對 C++ 歷史的個人觀點

            先把 PPT 放出來,文章以后有空再寫吧。

            cpp_history

            幻燈片2

            幻燈片3

            幻燈片4

            幻燈片5

            幻燈片6

            幻燈片7

            幻燈片8

            幻燈片9

            幻燈片10

            幻燈片11

            幻燈片12

            幻燈片13

            幻燈片14

            幻燈片15

            幻燈片16

            cpp_history17

            幻燈片18

            幻燈片19

            cpp_history20

            幻燈片22

            幻燈片23

            cpp_history24

            幻燈片25

            cpp_history26

            幻燈片27

            幻燈片28

            幻燈片29

            解釋:integers 固定長度有什么好處?或者說為什么 <stdint.h>  typedefs 沒有解決問題?

            1. 格式化輸入輸出 scanf/printf,int64_t 應該用什么格式?"%d" 還是 "%ld" 還是 "%lld" ? int_fast32_t 呢?

            C99 為了解決這個,引入了 inttypes.h 頭文件,其中定義了一堆宏,類似 PRId32, PRId64, PRIdFAST32,代碼寫起來是這樣:

            int64_t value = getValue();

            printf("value = " PRId64 "\n", value);

            2. 在 C++ 里,可以用函數重載 (overload) 來解決。但是 typedef 并不真正引入新類型(golang 與此不同),你如何知道 int_fast32_t 與 int64_t 是不是同一類型呢?另外還有 size_t/time_t 呢。比如

            void foo(uint64_t x)

            {}

            void foo(size_t x)

            {}

            在有的系統(64 位 Linux)下會報編譯錯,因為 size_t 和 uint64_t 都是 unsigned long 類型,不能重載 foo 兩次。怎么辦?用宏和條件編譯嗎?

             

            另外的例子是 time_t 和 int64_t:

            void bar(time_t y)

            {}

            void bar(int64_t y)

            {}

            這段代碼有錯沒錯?取決于 time_t 與 int64_t 是不是同樣的 typedef,如果整數不定長,除了用丑陋的 #if / #endif 條件編譯,有辦法解決嗎?

            幻燈片30

            解釋1:finally 有什么用?確實可以用棧上對象析構函數里的動作來模擬 finally,這又是一個 idiom,為什么不正大光明地讓語言支持這一常用功能呢?

             

            解釋2:數據成員的默認值有什么用?

            如果 class Foo 有一個 enum State state_; 成員,希望初始化為 INVALID_STATE。而 Foo 有 4 個構造函數,那么你得在每個構造函數里寫:

            Foo::Foo()

            : state_(INVALID_STATE)

            {}

            Foo::Foo(XXXX1)

            : state_(INVALID_STATE)

            {}

            Foo::Foo(XXXX1, YYYY2)

            : state_(INVALID_STATE)

            {}

            Foo::Foo(XXXX1, YYYY2, ZZZZ3)

            : state_(INVALID_STATE)

            {}

            state_ 的初始化要寫四處。對于 enum,或許還可以用一個公用的 init() 來初始化。那么對于 class-type 如 string/vector,用 init() 這種辦法就不能享受 initialization list 的好處了,因為對象在構造之后再被賦值,重復勞動。

            更糟糕的是,萬一你將來加了一個 int turnedOn_ 成員,初始值為 -1,你得在 4 個構造函數那里去增加初始化代碼,萬一漏了一處,等待你的就是 uninitialized value,自求多福吧。

            cpp_history31

            關于 allocator,它沒有帶來任何好處,如果內存分配這種事情都需要重新定義,重寫數據結構也是理所應當的:

            http://blog.csdn.net/Solstice/archive/2009/08/02/4401382.aspx

             

            auto_ptr 為什么是壞的,因為太容易用錯,且不能放到標準容器里。

            Gregory Colvin 最早設計的 auto_ptr 是沒有“所有權轉移”這個語意的,跟現在的 scoped_ptr 一樣。但是標準委員會莫名其妙地加了這個語意,造成了很多陷阱。

            scoped_ptr/unique_ptr/shared_ptr 都是更好的替代,語意明確,不容易用錯。

             

            至于為什么 valarray 是壞的,見《C++ 標準程序庫》相關章節,再說,有誰會用 valarray 做科學計算嗎?同樣壞的還有 vector<bool>。

             

            如果 XML/logging 這些基本構件不標準化,很難讓幾個第三方庫協作起來,因為每個庫都會自己發明一套互不兼容的 logging 和 XML 處理機制。

            如果程序里要把 library A 生成的 XML 對象傳到 library B 里,恐怕只好用字符串來作為中間媒介,這會增加很多無謂序列化/反序列化的開銷。

            logging 也是如此,如果沒有標準化接口,如何讓 library A 和 library B 按相同的格式寫到同一個日志文件呢?恐怕又得自己寫寫 adapter 來協調這些第三方庫了。

            幻燈片32

            posted on 2010-04-06 21:34 陳碩 閱讀(8452) 評論(25)  編輯 收藏 引用

            評論

            # re: 對 C++ 歷史的個人觀點 2010-04-06 22:38 OwnWaterloo

            個人覺得很多改進都是不切實際的。

            —— Exact-width integer types

            沒有必要。
            當需要確定寬度的整數類型時, 應該使用stdint.h那樣的typedef。(據說C++0x也會引入相應的cstdint)
            而不是一開始就將數據類型固定死。

            而且,即使是C99, Exact-width integer types也是optional的。
            也就是說,確實是不能保證在每個平臺上都有確定寬度整數。
            更有用的應該是Minimum-width integer types
            或者Fastest minimum-width integer types

            —— finally
            引入finally還不如引入lambda和auto。
            有了lambda和auto, 配合RAII, finally就不值錢了。
            而lambda和auto也是C++0x準備加入的。

            —— default value
            這能有什么用?
            C和C++給程序員最大限度的控制。

            struct X x;
            X_fill(&x); // 明明知道x馬上就會被fill, 初始化也是多余的。

            如果確實需要:
            struct X x_default_initialized = X();


            —— allocator
            絕對是需要的。 你用不上不等于別人用不上。

            如果去掉allocator, 當那個默認的allocator不滿足你的需要時,報銷的(不能被復用的)不僅僅是那個默認的allocator, 而是連同整個data structure庫都廢掉。

            而加上allocator并不會引起什么害處。
            別說“vector<int, my_allocator> 和vector<int> 不是同一類型”什么的。
            當你確實需要這種行為時, 他們本來就不應該是一個類型。

            —— auto_ptr和valarray
            不知道這兩位又怎么了。
            是不是boost::scope_ptr比 const std::auto_ptr新潮?
            而在C++加入restrict 之前, valarray都是有用的, 只是你可能用不上而已。



            —— 其他的庫
            只有threading是必須加入語言的。
            因為語言不提供幫助的話, threadding庫是搞不出來的。

            而其他的network, xml, log,就越界了。

            C++不是那些有大公司撐腰的語言, 可以對標準庫肆意的擴充。
              回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-06 22:50 Sunshine Alike

            mark,期待博主文章也放出來~  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 00:26 陳碩

            @OwnWaterloo
            已在正文中答復。  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 01:58 OwnWaterloo

            ———— integers

            >> integers 固定長度有什么好處?或者說為什么 <stdint.h> typedefs 沒有解決問題?

            scanf/printf這個你已經說了, inttypes.h
            而cin/cout更不用說了, 因為有重載。

            >> 在 C++ 里,可以用函數重載 (overload) 來解決。但是 typedef 并不真正引入新類型(golang 與此不同),你如何知道 int_fast32_t 與 int64_t 是不是同一類型呢?另外還有 size_t/time_t 呢
            你真的需要嗎? 真的需要有is_same_type這種東西。

            你通常你需要做的就是像cin/cout那樣, “對類型本身, 而不是各種typedef”去重載。
            比如:
            void f(char x); void f(int x); ...
            然后無論uint64_t和size_t是什么, 都可以f之。

            或者使用enable_if這種機制。

            java和C#那套東西, 只是在當前的pc機已經服務器上行得通。
            比如它們要規定整數長度, 規定浮點規格, 甚至連char都規定了。
            但這是很短視的作法。

            這兩門語言所說的unicode, 其實只是utf16。
            我不知道usc4流行起來的時候, 這兩門語言打算怎么辦?
            又搞出個wchar?
            或許那時候它們早就滅亡了。

            而對其他各種古怪的平臺, 我也不知道java se和.net compact活得怎樣。
            我只想知道, 在16位的平臺上, 32位的int是否總是要由2個機器字拼出來。
            甚至, 在8位平臺上, 是否需要4個機器字來拼。

            而這兩門語言又希望做到強類型, short的使用不是那么愉快:
            short s = ...;
            s = s + 1; // error
            s += 1; // ok

            C語言肯定是打算盡可能貼近機器的, 而不是貼近程序員的。
            所以C標準不會規定確定長度的整數, 即使C99中, 那些typedefs也是optional的。

            而C++, 這個就有分歧了。
            我是希望C++依然能貼近機器。
            畢竟, 如果真的需要開發起來很爽, 已經有java或者C#了, 直接用就是了。

            如果讓C++規定整數長度, 而提供:
            typedef xxx nature_width_t;
            并大量使用之, 我覺得很難接受。



            ———— finally

            >> finally 有什么用?確實可以用棧上對象析構函數里的動作來模擬 finally,這又是一個 idiom,為什么不正大光明地讓語言支持這一常用功能呢?

            這一功能常用嗎? 在我看來, 它只是沒有確定性析構時機的語言中的一種“補救措施”。
            不能因為其他語言有這個, 就一定要搬到C++中。

            C++不需要這種爛玩意, 請允許我說它是爛玩意。
            為什么? 因為finally會造成“執行代碼與回滾代碼”分離兩處 —— 相信你明白我的意思。
            所以C#會早早引入using, 而不思進取的java也終于打算在java7加入類似的機制。

            所以, 這種東西只會讓代碼寫得更爛, 而不是更好。
            這是最主要的原因。


            其次, “讓資源歸類所有”, 這在C++中已經被廣泛接受了, 是這樣嗎?
            所以, 在很多時候, C++都可以將action和rollback寫在一處。
            而實現一個范型的RRID類, 其實Loki已經有ScopeGuard而boost也有scope_exit。
            當語言支持auto和lambda之后, 它們都不再需要使用語言的陰暗角落或者晦澀的語法。
            可以實現的十分優雅, 用戶代碼也可以寫的十分優雅。

            而且auto的實現并不難, 編譯器必然是知道某個表達式的類型。
            lambda應該也不難, 很多時候那些手寫的functor都是有規律的, 很適合讓機器自動生成的。
            而finally的實現方式, 我就不清楚了。

            ———— 默認值

            >>解釋2:數據成員的默認值有什么用?

            我依然沒看出有什么用。
            你舉的例子, 其實是C++0x打算支持的“轉發構造函數”可以優美解決的。

            而且, 據我所知, C++0x也是打算支持這樣的特性的, 我忘記叫什么名字了:
            class X {
            T v = default_value_for_v;
            };

            注意, 我的觀點不是排斥這種特性。
            我反對的是將這種行為“作為默認行為”。
            我希望默認情況下, 語言不要做多余的事情, 除非我顯示要求。

            —— allocator
            我看了你給的鏈接, 沒發現有具有說服力的例子。

            1. 當你不需要定制allocator。

            無論那種設計, 都不會對你造成影響。

            2. 當你需要定制allocator。

            無論那種設計, 你可能都需要將兩種容器區別對待。
            也就是說, 你這種要求:
            >>但這完全沒道理,我不過想訪問一個vector<string>,根本不關心它的內存是怎么分配的,卻被什么鬼東西allocator擋在了門外。

            不過想訪問一個vector<string>的要求, 本來就是不合理的。
            你只考慮到了“使用allocator會有什么壞處”, 卻沒想過“不使用allocator你同樣會遇到這些問題”。
            所以, 這并不是allocator的錯。

            而使用allocator的設計, 你至少不需要去重新實現一套數據結構。

            當然, STL對allocator的設計并不是很好。
            比如它要求不同的allocator必須被認為是同一個。
            所以會導致這樣的問題:
            >> 那么每種類型的allocator必須是全局唯一的(Singleton)

            C++應該取消這個限制, 而不是取消allocator。


            在你所說parser的case中, 你的目標是這樣對嗎:
            一個allocator的類型有不同的實例, 這些實例是不在線程之間共享的。

            那么, 這些container本身也是不在線程間共享, 依然可以用allocator解決。
            只是它會觸犯STL對allocator的限制。


            —— 各種庫, auto_ptr, valarray, xml, log

            >>auto_ptr 為什么是壞的,因為太容易用錯,且不能放到標準容器里。

            C++什么東西是“不容易用錯的”?
            (而且, 當你允許工程使用boost之后, 你會遇到更多容易用錯的東西)


            這和finally還不同。
            學會finally之后, 寫出的代碼依然是臭的。
            而auto_ptr, 至少在學會之后, 它還是有用的。


            valarray的slice我還確實沒用過。


            對, auto_ptr, valarray, vector<bool> 都是有各種各樣的毛病的。
            但是, 既然他們已經被加入標準庫了, 對付這些毛病的辦法就是去“學”。
            移除是沒法移除的。 早就被deprecated的strstream到現在都可以使用。
            vc10, gcc4.4.0), vc10甚至一個警告都不給。

            而且, 它們(包括strstream)對會使用的人來說并不是一無是處。
            就我來說, 我并不需要scoped_ptr, 或者說不會因為這樣一個小東西去引入boost,或者將編譯器限制到支持C++0x的那些上。

            vector<bool> 和valarray都是試驗品。
            如果你需要一個可增長的位圖, 你還是得去實現vector<bool>那樣的東西。
            使用上還是需要注意將他們和STL其他容器有所區分。
            那么, 移除它能獲得什么好處?

            valarray就讓它呆那里就可以了, 會給你帶來負擔嗎?


            —— xml和log

            你說的這個問題, 是不能靠語言提供標準庫來做的。
            很簡單, Qt用std::string了嗎? ACE用了嗎? MFC用了嗎?


            你可以說std::string設計得差, 設計得太學術。
            你也可以說上面那些庫不屑于使用模板。

            但是, std::xml, std::log難道不會重蹈覆轍?
            上面討論的那幾個家伙(auto_ptr, valarray, vector<bool>)已經犯錯了。

            同時, 正因為我們看到這些不夠完美的東西, 對待標準庫時我們更需要“謹慎”。
            我覺得標準委員會做得很好, 甚至將concepts砍了都做得很好。
            就是兩個字“謹慎”。
            沒有它們, 依然還在開發; 但如果因為沖動加入它們, 可能就是以后無法移除的負擔。
            就像上面那幾個。

            目前這種模式: 將boost作為試驗田, 等有充分使用基礎之后再納入tr1, 我也覺得很好。


            C++需要的是穩定, 只把必須加入語言的東西加入,(移除就更沒必要了) 其他的慢慢觀望。
            我寧愿使用一個從vc8-vc10, 從gcc3-gcc4都可以使用的C++。
            而不是告訴用戶, 你必須使用什么編譯器的什么版本。

            C++不像C#那樣, 可以霸氣的說“我就是不向后兼容,你拿我怎么招?” “你不還是得用我?”
              回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 08:40 ccsdu2009

            搞不明白的是很多國人做ppt總喜歡搞英文的 納悶  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點[未登錄] 2010-04-07 09:38 hh

            @ccsdu2009
            眼界低不怪你, 等你明白了就好了.  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 10:35 溪流

            搬凳子學習  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 10:55 溪流

            C++ 1x 確定了?  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 12:30 wuqq

            @OwnWaterloo
            關于vector<T> 與vector<T, Allocator>,我是這么看的:首先明確的一個概念是接口還是實現,任何暴露其內部實現的接口都不是好的設計。那么Allocator是實現還是接口呢,我傾向于把它看成是實現,vector就是一段連續的內存,至于怎么分配內存,那是你內部實現的事。你可以看到在c++0x的tr1庫中,function, shared_ptr都是可以內存定制的,但在類型聲明中都沒有allocator模板參數,這就是設計思想的改變。  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 12:54 陳梓瀚(vczh)

            @wuqq
            有些時候你并不能拿C++的接口跟其他語言的interface等同。舉個例子,如果你的vector沒有allocator這個模板參數,而是在構造函數里面需要一個IAllocator<T>*,你認為使用的時候方便嗎?

            在給C++寫類的時候,你做的不是在完成一個功能,而是在擴充語言讓C++變得更強大。  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 13:48 wuqq

            @陳梓瀚(vczh)
            1)難道你忘記了可以取默認值。比如構造函數:
            vector(allocator_ptr a = default_allocator());
            或者干脆使用重載寫成兩個函數。
            2)老大,我只是寫一個類而已,我就是要完成一個功能,我干嘛要擴充語言。
            3) 我不知道C++的接口特殊在什么地方,事實上,我覺得大部分C++程序員的接口都設計得很濫,“C++傾向于過分復雜的設計”——《UNIX編程藝術》的作者N年前就說出了這樣的話。  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 16:37 OwnWaterloo

            @wuqq
            C++不玩那套, 別拿其他語言的什么接口/實現那套玩意來“套”C++的設計。
            allocator是一種規范。
            整個STL都是在這種duck typing的基礎上構建起來的, 而不是java或者C#那種接口式的設計。


            如果你確實需要按接口的方式來使用, 自己實現一個滿足allocator規范的接口, 假設叫IA。
            然后使用vector<T,IA> 即可。
            無論你使用什么IA的實現, 你都可以使用vector<T,IA>類型。
            甚至可以使用0x中的新的特性:
            template<typename T>
            using your_vector = std::vector<T,your_allocator<T>>;
            your_allocator是一個模板, 轉發到IA上。

            然后就一直使用your_vector就行了。


            模板和接口就是在效率與代碼體積上的權衡。
            但是, 用模板實現的代碼, 如果在乎代碼體積, 可以輕易轉換為接口去使用。
            并且獲得接口的所有好處, 例如不暴露實現。
            反之, 如果一開始就用接口,當需要模板的行為時, 就沒得搞, 永遠沒辦法, 除了重寫。


            vector太麻煩, 換個例子。
            如果將排序算法使用模板實現:
            template<class RanIt, class Cmp>
            void sort(RanIt first, RanIt last, Cmp c);

            那么, 這個模板可以輕易轉換為C語言中使用void*和int (*cmp)( ... )的qsort, 也可以輕易轉換為使用接口作為Cmp和RanIt的sort。
            同時, 不暴露這個模板的任何實現。
            你可以將這個模板隱藏到實現文件中。

            反之, 如果sort一開始就是qsort或者使用接口:
            當你確實需要效率,確實針對不同類型生成另一套代碼的時候, 你必須重寫。

            這就是模板的強大之處, 它的使用是很靈活的, 看你的需求而定。
            你不僅僅可以“直接使用”, 你還可以將它作為“代碼生成器”, 生成滿足你需要的東西。
              回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 17:15 陳梓瀚(vczh)

            @OwnWaterloo
            當然這是其中一種觀點,不過從語言設計的角度出發,我認為C++沒有interface的根本原因是不需要,因為它有多重繼承。而且因為模板的類型推導非常強大(優化也是其中一個方面),因此interface的概念也就被弱化了。

            不過有些時候使用接口的話,可以避免很多因為想寫出優美的句子的同時造成模板膨脹過于厲害。第一個例子自然是boost::spirit了,已經嚴重到了讓編譯器浪費人類時間的地步了,這個網上有的是抱怨,我也就不多說了。第二個例子就是linq了。當然我并不說這跟stl比起來有什么優勢,假設實現linq就是一個前提,因為linq的特點就是algorithm無敵多,并且algorithm返回自己的iterator,而且鼓勵N個algorithm嵌套使用,跟不同的iterator結合起來代碼膨脹速度會變得非常快(無論是list&gt;&gt;Where(a)&gt;&gt;Select(b)&gt;&gt;Aggregate(i,C)也好,還是Aggregate(i,Select(Where(list, a), b))也好)。做的時候會發現Where和Select返回的iterator基本上都必須是一個全新類型,結果就是假如你不使用純虛類當接口,那么每一行都會構造一個全新類型,當你的程序充滿linq的時候就不得了了(想象一下spirit)。【當然值不值得實現linq那不討論】

            第二種情況就是,有些人可能會覺得編譯器盡早告訴你錯誤比運行時的那點開銷更重要,那么他會用純虛類當接口去模仿concept。

            第三種情況就是,有些時候你為了寫成dll,不得不不使用模板……而且很有諷刺意味的是,大部分人寫dll完全是因為有人(不一定是寫dll的人自己)覺得他帥。  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 17:33 空明流轉

            @陳梓瀚(vczh)
            你別老拿Spirit說事兒啊。我等著你的東西呢。。。。  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 17:58 陳梓瀚(vczh)

            @空明流轉
            TM我前天labtop出問題了啊……  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 19:17 volnet

            標記一下,郁悶啊,昨天在你CSDN看的,一點注釋都沒有,這里原來版本有改進……還有很多回復,晚上回去洗把臉再看  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 20:50 唐風

            @OwnWaterloo
            很精彩,呵呵。
            關于allocator這段,我看得很仔細,因為,在TopLanguage里,有一個主題是《{技術}{C++} 突然有一種想法:將文本文件讀入vector可以跨過push_­back()嗎》
            http://groups.google.com/group/pongba/browse_thread/thread/ebb85b7e927c1af9/aebc1741ed60b2f5?hl=zh-CN&lnk=gst&q=%E7%AA%81%E7%84%B6%E6%9C%89%E4%B8%80%E7%A7%8D%E6%83%B3%E6%B3%95%EF%BC%9A%E5%B0%86%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E8%AF%BB%E5%85%A5vector%E5%8F%AF%E4%BB%A5%E8%B7%A8%E8%BF%87push_back()%E5%90%97#
            我在里面表達了與OwnWaterloo同樣的觀點,但我的認證和說明膚淺多了。我剛剛還特別翻了下,發現當時的“辯方對友”居然正是樓主,世界太小了(樓主也是牛人,哪都見得到滴說)。

            在這個問題上,我與OwnWaterloo相同,并從他的回答中又學到不少東西。我喜歡這樣的“技術論戰”,因為它總是能讓人進步,呵呵。向樓主,和OwnWaterloo學習。

              回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-07 21:25 OwnWaterloo

            @唐風
            TL上跑題太嚴重, 看吧, 沒幾樓就扯到profiling, 扯到“大部分應用都合適了”。
            如果萬事都扯這么多無關的東西, 就沒什么好討論了。

            allocator的問題不在于是否應該有allocator參數,是否應該將allocator作為模板參數。
            上面已經說了:

            1. 如果一個container沒有allocator參數
            那它內部的分配方式必然不能被定制, 它綁定了一個“策略”。
            當這種策略無法滿足用戶要求時, 整個container的實現連同這個策略一起被拋棄。

            2. 模板vs非模板參數
            上面也說了, 模板是非模板的一個范化形式。
            模板可以得到非模板的東西, 只要實例化一次即可。
            反之不行。
            當template alias加入語言后, 使用模板的設計會更優雅。


            allocator真正的問題是標準對allocator的狀態的描述很模糊。

            如果同一allocator type的所有instance都可以被認為是相同的 —— 也就是說,A和B是同一個個類型的2個instance, 從A分配的內存可以由B釋放 —— 那沒問題, 可以安全的和STL配合使用。

            但通常, allocator都需要per instance的狀態才能發揮真正作用。
            而這種帶有per instance狀態的allocator和STL交互, 標準說得很模糊。

            如果標準規定STL的實現必須注意這個問題, 那allocator就非常好用。
            絕對不存在lz所說的“基本用不上”。
            即使就是現在的情況, 也可以用一些方式繞過去, 只是很不美觀。

            綜上, allocator的設計應該被改進(取消這個限制), 而且依然作為一個模板參數。


            btw:如果C++0x真引入了template alias,boost的智能指針就是一坨垃圾, 無論它設計多少個, 在Loki面前都是垃圾。
              回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-09 01:04 欲三更

            —— xml和log

            你說的這個問題, 是不能靠語言提供標準庫來做的。
            很簡單, Qt用std::string了嗎? ACE用了嗎? MFC用了嗎?

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

            這一句說的太好了,C++很大一部分的混亂的起因不是“沒有標準實現”——當然很多時候確實沒有標準實現,而是大家都要去實現。而且,那boost來說,boost曾經拒掉一個log方面的庫,但是就算是boost里面有這個庫,有多少人會去用?很多時候不是主觀上不喜歡用,而是說boost,包括像stl這種東西,它們的編程哲學太強勢,并且經常迥異于我們慣常的代碼。  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-09 11:03 陳碩

            @欲三更
            這正好證明了我的觀點,如果標準庫里沒有,每個第三方 library 都會自己造一套。
            std::string 加入標準大約是在 1994 年,然后又被 STL 拖延,到 1998 年標準才發布。
            而 QT, ACE, MFC 的開發均早于 std::string。
            QT 是 1991 年開始開發,MFC 最早在 1992 年發布,1993 年 ACE 的版本號已經升到了 2.12。

            假如 C++ 在 1985 年提供 string,還會造成這樣天下大亂的局面嗎?  回復  更多評論   

            # re: 對 C++ 歷史的個人觀點 2010-04-09 16:58 OwnWaterloo

            @陳碩
            MFC、QT、ACE太老是吧? 來個新點的?
            http://www.libnui.net/

            去看看它是什么時候開始開發的, 又重復發明了多少輪子吧。
              回復  更多評論   

            # re: 對 C++ 歷史的個人觀點[未登錄] 2010-04-11 10:57 chentan

            http://www.libnui.net/

            這個東東不穩定啊,他那個生成器,我隨便拖兩下鼠標就崩潰了  回復  更多評論   

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導航

            統計

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久无码高潮喷水| 性欧美丰满熟妇XXXX性久久久 | 国产成年无码久久久久毛片| 一本大道久久东京热无码AV| 久久久久亚洲av成人网人人软件 | 综合人妻久久一区二区精品| 久久精品国产亚洲av水果派| 久久青青草原精品影院| 久久久黄片| 久久香综合精品久久伊人| 国产精品视频久久久| 最新久久免费视频| 国产精品久久免费| 亚洲精品乱码久久久久久自慰| 热99re久久国超精品首页| 久久青青草视频| 成人精品一区二区久久久| 国产一区二区久久久| 国产精品成人99久久久久91gav| 精品久久久久久中文字幕大豆网 | 人妻无码精品久久亚瑟影视| 久久99中文字幕久久| 无码精品久久久天天影视| 老司机午夜网站国内精品久久久久久久久| 久久亚洲中文字幕精品有坂深雪| 久久人妻少妇嫩草AV蜜桃| 久久精品成人免费看| 久久久久久亚洲精品成人| 无码人妻久久一区二区三区蜜桃 | 69久久夜色精品国产69| 久久婷婷五月综合国产尤物app | 伊人色综合久久天天人手人婷| 99久久精品国产一区二区三区| 精品无码久久久久久尤物| 欧美熟妇另类久久久久久不卡| 精品久久久一二三区| 亚洲午夜无码久久久久小说 | 青青草原精品99久久精品66| 久久久久免费精品国产| 久久亚洲AV成人无码软件| 久久精品国产男包|