• <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 應(yīng)該用什么格式?"%d" 還是 "%ld" 還是 "%lld" ? int_fast32_t 呢?

            C99 為了解決這個,引入了 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)下會報編譯錯,因為 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,如果整數(shù)不定長,除了用丑陋的 #if / #endif 條件編譯,有辦法解決嗎?

            幻燈片30

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

             

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

            如果 class Foo 有一個 enum State state_; 成員,希望初始化為 INVALID_STATE。而 Foo 有 4 個構(gòu)造函數(shù),那么你得在每個構(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_ 的初始化要寫四處。對于 enum,或許還可以用一個公用的 init() 來初始化。那么對于 class-type 如 string/vector,用 init() 這種辦法就不能享受 initialization list 的好處了,因為對象在構(gòu)造之后再被賦值,重復(fù)勞動。

            更糟糕的是,萬一你將來加了一個 int turnedOn_ 成員,初始值為 -1,你得在 4 個構(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 為什么是壞的,因為太容易用錯,且不能放到標(biāo)準(zhǔn)容器里。

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

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

             

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

             

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

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

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

            幻燈片32

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

            評論

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

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

            —— Exact-width integer types

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

            而且,即使是C99, Exact-width integer types也是optional的。
            也就是說,確實是不能保證在每個平臺上都有確定寬度整數(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馬上就會被fill, 初始化也是多余的。

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


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

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

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

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



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

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

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

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

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

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

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

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

            ———— integers

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

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

            >> 在 C++ 里,可以用函數(shù)重載 (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這種機(jī)制。

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

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

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

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

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

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

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



            ———— finally

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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

            >>auto_ptr 為什么是壞的,因為太容易用錯,且不能放到標(biāo)準(zhǔn)容器里。

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


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


            valarray的slice我還確實沒用過。


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

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

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

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


            —— xml和log

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

              回復(fù)  更多評論   

            # re: 對 C++ 歷史的個人觀點 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. 如果一個container沒有allocator參數(shù)
            那它內(nèi)部的分配方式必然不能被定制, 它綁定了一個“策略”。
            當(dāng)這種策略無法滿足用戶要求時, 整個container的實現(xiàn)連同這個策略一起被拋棄。

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


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

            如果同一allocator type的所有instance都可以被認(rèn)為是相同的 —— 也就是說,A和B是同一個個類型的2個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的實現(xiàn)必須注意這個問題, 那allocator就非常好用。
            絕對不存在lz所說的“基本用不上”。
            即使就是現(xiàn)在的情況, 也可以用一些方式繞過去, 只是很不美觀。

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


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

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

            —— xml和log

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

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

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

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

            @欲三更
            這正好證明了我的觀點,如果標(biāo)準(zhǔn)庫里沒有,每個第三方 library 都會自己造一套。
            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 的版本號已經(jīng)升到了 2.12。

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

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

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

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

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

            http://www.libnui.net/

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


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


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

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久久久精品成人热色戒| 日本精品久久久久影院日本| 久久99精品国产一区二区三区| 青青热久久国产久精品 | 国内精品伊人久久久久影院对白| 国内精品伊人久久久久777| 久久99国产精品成人欧美| 亚洲国产香蕉人人爽成AV片久久| 久久精品99无色码中文字幕| 72种姿势欧美久久久久大黄蕉| 亚洲精品乱码久久久久久蜜桃不卡| 性做久久久久久久久| 久久综合久久自在自线精品自| 国产美女亚洲精品久久久综合| 久久久久久免费一区二区三区| 精品国际久久久久999波多野 | 91精品国产91久久久久久| 国产精品久久久久…| 伊色综合久久之综合久久| 性做久久久久久久久浪潮| 国产精品久久久久影院色 | 久久精品草草草| 久久亚洲精精品中文字幕| 亚洲AV伊人久久青青草原| 国产69精品久久久久99| 久久九九久精品国产免费直播| 久久综合给久久狠狠97色| 久久精品一区二区三区AV| 久久93精品国产91久久综合| 色噜噜狠狠先锋影音久久| 久久综合给合久久国产免费 | 亚洲精品午夜国产VA久久成人| 久久久久久久综合日本| 久久久91人妻无码精品蜜桃HD| 亚洲国产成人久久精品影视| 国内精品久久久久影院免费| jizzjizz国产精品久久| 精品永久久福利一区二区| 久久久久久久97| 国产巨作麻豆欧美亚洲综合久久| 国产99久久精品一区二区|