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

            對(duì) C++ 歷史的個(gè)人觀點(diǎn)

            先把 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 固定長(zhǎng)度有什么好處?或者說為什么 <stdint.h>  typedefs 沒有解決問題?

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

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

            int64_t value = getValue();

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

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

            void foo(uint64_t x)

            {}

            void foo(size_t x)

            {}

            在有的系統(tǒng)(64 位 Linux)下會(huì)報(bào)編譯錯(cuò),因?yàn)?size_t 和 uint64_t 都是 unsigned long 類型,不能重載 foo 兩次。怎么辦?用宏和條件編譯嗎?

             

            另外的例子是 time_t 和 int64_t:

            void bar(time_t y)

            {}

            void bar(int64_t y)

            {}

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

            幻燈片30

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

             

            解釋2:數(shù)據(jù)成員的默認(rèn)值有什么用?

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

            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_ 的初始化要寫四處。對(duì)于 enum,或許還可以用一個(gè)公用的 init() 來初始化。那么對(duì)于 class-type 如 string/vector,用 init() 這種辦法就不能享受 initialization list 的好處了,因?yàn)閷?duì)象在構(gòu)造之后再被賦值,重復(fù)勞動(dòng)。

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

            cpp_history31

            關(guān)于 allocator,它沒有帶來任何好處,如果內(nèi)存分配這種事情都需要重新定義,重寫數(shù)據(jù)結(jié)構(gòu)也是理所應(yīng)當(dāng)?shù)模?/p>

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

             

            auto_ptr 為什么是壞的,因?yàn)樘菀子缅e(cuò),且不能放到標(biāo)準(zhǔn)容器里。

            Gregory Colvin 最早設(shè)計(jì)的 auto_ptr 是沒有“所有權(quán)轉(zhuǎn)移”這個(gè)語意的,跟現(xiàn)在的 scoped_ptr 一樣。但是標(biāo)準(zhǔn)委員會(huì)莫名其妙地加了這個(gè)語意,造成了很多陷阱。

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

             

            至于為什么 valarray 是壞的,見《C++ 標(biāo)準(zhǔn)程序庫》相關(guān)章節(jié),再說,有誰會(huì)用 valarray 做科學(xué)計(jì)算嗎?同樣壞的還有 vector<bool>。

             

            如果 XML/logging 這些基本構(gòu)件不標(biāo)準(zhǔn)化,很難讓幾個(gè)第三方庫協(xié)作起來,因?yàn)槊總€(gè)庫都會(huì)自己發(fā)明一套互不兼容的 logging 和 XML 處理機(jī)制。

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

            logging 也是如此,如果沒有標(biāo)準(zhǔn)化接口,如何讓 library A 和 library B 按相同的格式寫到同一個(gè)日志文件呢?恐怕又得自己寫寫 adapter 來協(xié)調(diào)這些第三方庫了。

            幻燈片32

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

            評(píng)論

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-06 22:38 OwnWaterloo

            個(gè)人覺得很多改進(jìn)都是不切實(shí)際的。

            —— Exact-width integer types

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

            而且,即使是C99, Exact-width integer types也是optional的。
            也就是說,確實(shí)是不能保證在每個(gè)平臺(tái)上都有確定寬度整數(shù)。
            更有用的應(yīng)該是Minimum-width integer types
            或者Fastest minimum-width integer types

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

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

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

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


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

            如果去掉allocator, 當(dāng)那個(gè)默認(rèn)的allocator不滿足你的需要時(shí),報(bào)銷的(不能被復(fù)用的)不僅僅是那個(gè)默認(rèn)的allocator, 而是連同整個(gè)data structure庫都廢掉。

            而加上allocator并不會(huì)引起什么害處。
            別說“vector<int, my_allocator> 和vector<int> 不是同一類型”什么的。
            當(dāng)你確實(shí)需要這種行為時(shí), 他們本來就不應(yīng)該是一個(gè)類型。

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



            —— 其他的庫
            只有threading是必須加入語言的。
            因?yàn)檎Z言不提供幫助的話, threadding庫是搞不出來的。

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

            C++不是那些有大公司撐腰的語言, 可以對(duì)標(biāo)準(zhǔn)庫肆意的擴(kuò)充。
              回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-06 22:50 Sunshine Alike

            mark,期待博主文章也放出來~  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 00:26 陳碩

            @OwnWaterloo
            已在正文中答復(fù)。  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 01:58 OwnWaterloo

            ———— integers

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

            scanf/printf這個(gè)你已經(jīng)說了, inttypes.h
            而cin/cout更不用說了, 因?yàn)橛兄剌d。

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

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

            或者使用enable_if這種機(jī)制。

            java和C#那套東西, 只是在當(dāng)前的pc機(jī)已經(jīng)服務(wù)器上行得通。
            比如它們要規(guī)定整數(shù)長(zhǎng)度, 規(guī)定浮點(diǎn)規(guī)格, 甚至連char都規(guī)定了。
            但這是很短視的作法。

            這兩門語言所說的unicode, 其實(shí)只是utf16。
            我不知道usc4流行起來的時(shí)候, 這兩門語言打算怎么辦?
            又搞出個(gè)wchar?
            或許那時(shí)候它們?cè)缇蜏缤隽恕?br>
            而對(duì)其他各種古怪的平臺(tái), 我也不知道java se和.net compact活得怎樣。
            我只想知道, 在16位的平臺(tái)上, 32位的int是否總是要由2個(gè)機(jī)器字拼出來。
            甚至, 在8位平臺(tái)上, 是否需要4個(gè)機(jī)器字來拼。

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

            C語言肯定是打算盡可能貼近機(jī)器的, 而不是貼近程序員的。
            所以C標(biāo)準(zhǔn)不會(huì)規(guī)定確定長(zhǎng)度的整數(shù), 即使C99中, 那些typedefs也是optional的。

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

            如果讓C++規(guī)定整數(shù)長(zhǎng)度, 而提供:
            typedef xxx nature_width_t;
            并大量使用之, 我覺得很難接受。



            ———— finally

            >> finally 有什么用?確實(shí)可以用棧上對(duì)象析構(gòu)函數(shù)里的動(dòng)作來模擬 finally,這又是一個(gè) idiom,為什么不正大光明地讓語言支持這一常用功能呢?

            這一功能常用嗎? 在我看來, 它只是沒有確定性析構(gòu)時(shí)機(jī)的語言中的一種“補(bǔ)救措施”。
            不能因?yàn)槠渌Z言有這個(gè), 就一定要搬到C++中。

            C++不需要這種爛玩意, 請(qǐng)?jiān)试S我說它是爛玩意。
            為什么? 因?yàn)閒inally會(huì)造成“執(zhí)行代碼與回滾代碼”分離兩處 —— 相信你明白我的意思。
            所以C#會(huì)早早引入using, 而不思進(jìn)取的java也終于打算在java7加入類似的機(jī)制。

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


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

            而且auto的實(shí)現(xiàn)并不難, 編譯器必然是知道某個(gè)表達(dá)式的類型。
            lambda應(yīng)該也不難, 很多時(shí)候那些手寫的functor都是有規(guī)律的, 很適合讓機(jī)器自動(dòng)生成的。
            而finally的實(shí)現(xiàn)方式, 我就不清楚了。

            ———— 默認(rèn)值

            >>解釋2:數(shù)據(jù)成員的默認(rèn)值有什么用?

            我依然沒看出有什么用。
            你舉的例子, 其實(shí)是C++0x打算支持的“轉(zhuǎn)發(fā)構(gòu)造函數(shù)”可以優(yōu)美解決的。

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

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

            —— allocator
            我看了你給的鏈接, 沒發(fā)現(xiàn)有具有說服力的例子。

            1. 當(dāng)你不需要定制allocator。

            無論那種設(shè)計(jì), 都不會(huì)對(duì)你造成影響。

            2. 當(dāng)你需要定制allocator。

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

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

            而使用allocator的設(shè)計(jì), 你至少不需要去重新實(shí)現(xiàn)一套數(shù)據(jù)結(jié)構(gòu)。

            當(dāng)然, STL對(duì)allocator的設(shè)計(jì)并不是很好。
            比如它要求不同的allocator必須被認(rèn)為是同一個(gè)。
            所以會(huì)導(dǎo)致這樣的問題:
            >> 那么每種類型的allocator必須是全局唯一的(Singleton)

            C++應(yīng)該取消這個(gè)限制, 而不是取消allocator。


            在你所說parser的case中, 你的目標(biāo)是這樣對(duì)嗎:
            一個(gè)allocator的類型有不同的實(shí)例, 這些實(shí)例是不在線程之間共享的。

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


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

            >>auto_ptr 為什么是壞的,因?yàn)樘菀子缅e(cuò),且不能放到標(biāo)準(zhǔn)容器里。

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


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


            valarray的slice我還確實(shí)沒用過。


            對(duì), auto_ptr, valarray, vector<bool> 都是有各種各樣的毛病的。
            但是, 既然他們已經(jīng)被加入標(biāo)準(zhǔn)庫了, 對(duì)付這些毛病的辦法就是去“學(xué)”。
            移除是沒法移除的。 早就被deprecated的strstream到現(xiàn)在都可以使用。
            vc10, gcc4.4.0), vc10甚至一個(gè)警告都不給。

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

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

            valarray就讓它呆那里就可以了, 會(huì)給你帶來負(fù)擔(dān)嗎?


            —— xml和log

            你說的這個(gè)問題, 是不能靠語言提供標(biāo)準(zhǔn)庫來做的。
            很簡(jiǎn)單, Qt用std::string了嗎? ACE用了嗎? MFC用了嗎?


            你可以說std::string設(shè)計(jì)得差, 設(shè)計(jì)得太學(xué)術(shù)。
            你也可以說上面那些庫不屑于使用模板。

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

            同時(shí), 正因?yàn)槲覀兛吹竭@些不夠完美的東西, 對(duì)待標(biāo)準(zhǔn)庫時(shí)我們更需要“謹(jǐn)慎”。
            我覺得標(biāo)準(zhǔn)委員會(huì)做得很好, 甚至將concepts砍了都做得很好。
            就是兩個(gè)字“謹(jǐn)慎”。
            沒有它們, 依然還在開發(fā); 但如果因?yàn)闆_動(dòng)加入它們, 可能就是以后無法移除的負(fù)擔(dān)。
            就像上面那幾個(gè)。

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


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

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

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 08:40 ccsdu2009

            搞不明白的是很多國人做ppt總喜歡搞英文的 納悶  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn)[未登錄] 2010-04-07 09:38 hh

            @ccsdu2009
            眼界低不怪你, 等你明白了就好了.  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 10:35 溪流

            搬凳子學(xué)習(xí)  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 10:55 溪流

            C++ 1x 確定了?  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 12:30 wuqq

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

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 12:54 陳梓瀚(vczh)

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

            在給C++寫類的時(shí)候,你做的不是在完成一個(gè)功能,而是在擴(kuò)充語言讓C++變得更強(qiáng)大。  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 13:48 wuqq

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

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 16:37 OwnWaterloo

            @wuqq
            C++不玩那套, 別拿其他語言的什么接口/實(shí)現(xiàn)那套玩意來“套”C++的設(shè)計(jì)。
            allocator是一種規(guī)范。
            整個(gè)STL都是在這種duck typing的基礎(chǔ)上構(gòu)建起來的, 而不是java或者C#那種接口式的設(shè)計(jì)。


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

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


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


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

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

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

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

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 17:15 陳梓瀚(vczh)

            @OwnWaterloo
            當(dāng)然這是其中一種觀點(diǎn),不過從語言設(shè)計(jì)的角度出發(fā),我認(rèn)為C++沒有interface的根本原因是不需要,因?yàn)樗卸嘀乩^承。而且因?yàn)槟0宓念愋屯茖?dǎo)非常強(qiáng)大(優(yōu)化也是其中一個(gè)方面),因此interface的概念也就被弱化了。

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

            第二種情況就是,有些人可能會(huì)覺得編譯器盡早告訴你錯(cuò)誤比運(yùn)行時(shí)的那點(diǎn)開銷更重要,那么他會(huì)用純虛類當(dāng)接口去模仿concept。

            第三種情況就是,有些時(shí)候你為了寫成dll,不得不不使用模板……而且很有諷刺意味的是,大部分人寫dll完全是因?yàn)橛腥耍ú灰欢ㄊ菍慸ll的人自己)覺得他帥。  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 17:33 空明流轉(zhuǎn)

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

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 17:58 陳梓瀚(vczh)

            @空明流轉(zhuǎn)
            TM我前天labtop出問題了啊……  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 19:17 volnet

            標(biāo)記一下,郁悶啊,昨天在你CSDN看的,一點(diǎn)注釋都沒有,這里原來版本有改進(jìn)……還有很多回復(fù),晚上回去洗把臉再看  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 20:50 唐風(fēng)

            @OwnWaterloo
            很精彩,呵呵。
            關(guān)于allocator這段,我看得很仔細(xì),因?yàn)椋赥opLanguage里,有一個(gè)主題是《{技術(shù)}{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#
            我在里面表達(dá)了與OwnWaterloo同樣的觀點(diǎn),但我的認(rèn)證和說明膚淺多了。我剛剛還特別翻了下,發(fā)現(xiàn)當(dāng)時(shí)的“辯方對(duì)友”居然正是樓主,世界太小了(樓主也是牛人,哪都見得到滴說)。

            在這個(gè)問題上,我與OwnWaterloo相同,并從他的回答中又學(xué)到不少東西。我喜歡這樣的“技術(shù)論戰(zhàn)”,因?yàn)樗偸悄茏屓诉M(jìn)步,呵呵。向樓主,和OwnWaterloo學(xué)習(xí)。

              回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-07 21:25 OwnWaterloo

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

            allocator的問題不在于是否應(yīng)該有allocator參數(shù),是否應(yīng)該將allocator作為模板參數(shù)。
            上面已經(jīng)說了:

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

            2. 模板vs非模板參數(shù)
            上面也說了, 模板是非模板的一個(gè)范化形式。
            模板可以得到非模板的東西, 只要實(shí)例化一次即可。
            反之不行。
            當(dāng)template alias加入語言后, 使用模板的設(shè)計(jì)會(huì)更優(yōu)雅。


            allocator真正的問題是標(biāo)準(zhǔn)對(duì)allocator的狀態(tài)的描述很模糊。

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

            但通常, allocator都需要per instance的狀態(tài)才能發(fā)揮真正作用。
            而這種帶有per instance狀態(tài)的allocator和STL交互, 標(biāo)準(zhǔn)說得很模糊。

            如果標(biāo)準(zhǔn)規(guī)定STL的實(shí)現(xiàn)必須注意這個(gè)問題, 那allocator就非常好用。
            絕對(duì)不存在lz所說的“基本用不上”。
            即使就是現(xiàn)在的情況, 也可以用一些方式繞過去, 只是很不美觀。

            綜上, allocator的設(shè)計(jì)應(yīng)該被改進(jìn)(取消這個(gè)限制), 而且依然作為一個(gè)模板參數(shù)。


            btw:如果C++0x真引入了template alias,boost的智能指針就是一坨垃圾, 無論它設(shè)計(jì)多少個(gè), 在Loki面前都是垃圾。
              回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-09 01:04 欲三更

            —— xml和log

            你說的這個(gè)問題, 是不能靠語言提供標(biāo)準(zhǔn)庫來做的。
            很簡(jiǎn)單, Qt用std::string了嗎? ACE用了嗎? MFC用了嗎?

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

            這一句說的太好了,C++很大一部分的混亂的起因不是“沒有標(biāo)準(zhǔn)實(shí)現(xiàn)”——當(dāng)然很多時(shí)候確實(shí)沒有標(biāo)準(zhǔn)實(shí)現(xiàn),而是大家都要去實(shí)現(xiàn)。而且,那boost來說,boost曾經(jīng)拒掉一個(gè)log方面的庫,但是就算是boost里面有這個(gè)庫,有多少人會(huì)去用?很多時(shí)候不是主觀上不喜歡用,而是說boost,包括像stl這種東西,它們的編程哲學(xué)太強(qiáng)勢(shì),并且經(jīng)常迥異于我們慣常的代碼。  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-09 11:03 陳碩

            @欲三更
            這正好證明了我的觀點(diǎn),如果標(biāo)準(zhǔn)庫里沒有,每個(gè)第三方 library 都會(huì)自己造一套。
            std::string 加入標(biāo)準(zhǔn)大約是在 1994 年,然后又被 STL 拖延,到 1998 年標(biāo)準(zhǔn)才發(fā)布。
            而 QT, ACE, MFC 的開發(fā)均早于 std::string。
            QT 是 1991 年開始開發(fā),MFC 最早在 1992 年發(fā)布,1993 年 ACE 的版本號(hào)已經(jīng)升到了 2.12。

            假如 C++ 在 1985 年提供 string,還會(huì)造成這樣天下大亂的局面嗎?  回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn) 2010-04-09 16:58 OwnWaterloo

            @陳碩
            MFC、QT、ACE太老是吧? 來個(gè)新點(diǎn)的?
            http://www.libnui.net/

            去看看它是什么時(shí)候開始開發(fā)的, 又重復(fù)發(fā)明了多少輪子吧。
              回復(fù)  更多評(píng)論   

            # re: 對(duì) C++ 歷史的個(gè)人觀點(diǎn)[未登錄] 2010-04-11 10:57 chentan

            http://www.libnui.net/

            這個(gè)東東不穩(wěn)定啊,他那個(gè)生成器,我隨便拖兩下鼠標(biāo)就崩潰了  回復(fù)  更多評(píng)論   


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


            <2010年4月>
            28293031123
            45678910
            11121314151617
            18192021222324
            2526272829301
            2345678

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊(cè)

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            A狠狠久久蜜臀婷色中文网| 久久97久久97精品免视看| 久久夜色精品国产欧美乱| 久久久老熟女一区二区三区| 韩国三级中文字幕hd久久精品| 国产精品久久久久久久久久影院| 久久香综合精品久久伊人| 品成人欧美大片久久国产欧美| 精品久久久无码人妻中文字幕| 青青草国产精品久久| 思思久久好好热精品国产| 久久精品国产亚洲av日韩| 亚洲国产成人精品久久久国产成人一区二区三区综 | 免费国产99久久久香蕉| 亚洲乱码日产精品a级毛片久久| 1000部精品久久久久久久久| 久久精品视频一| 青春久久| 精品久久久久一区二区三区| 男女久久久国产一区二区三区| 日韩电影久久久被窝网| 青青国产成人久久91网| 久久超乳爆乳中文字幕| 国产精品亚洲综合久久| 精品久久久久国产免费| 色综合久久88色综合天天| 久久久久高潮毛片免费全部播放 | 国产精品gz久久久| 久久国产高潮流白浆免费观看| 久久精品国产亚洲AV香蕉| 伊人色综合久久天天网| 日韩欧美亚洲综合久久影院Ds | 久久久久久A亚洲欧洲AV冫| 国产精品岛国久久久久| 国产V亚洲V天堂无码久久久| 色综合久久无码中文字幕| 亚洲精品乱码久久久久久中文字幕| 一本久久精品一区二区| 亚洲国产成人久久一区WWW| 久久中文字幕精品| 久久天天躁夜夜躁狠狠|