• <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 - 16,  comments - 34,  trackbacks - 0
            共10頁: First 2 3 4 5 6 7 8 9 10 
            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-17 20:54
            @visualfc
            Qt Creator我知道,Qt Creator的cplusplus是指的什么?
            Qt Creator的自動完成功能嗎?

            我看過你的一些作品,果然對這方面的東西了解很多~_~


            @陳梓瀚(vczh)
            其實我的需求上面也有說…… 就是將代碼染染色……
            不然直接在blog上貼代碼太丑陋了……
            re: XL Library Preview,誠征指點 OwnWaterloo 2009-11-17 20:21
            @溪流
            某人犯傻去繼承string,那是他的責任。
            沒有必要為了避免他的錯誤,讓所有人讓步,承受虛指針的開銷。

            反向迭代器,我猜的也是這么回時。
            不過具體沒看。
            去看看代碼吧,應該不多。
            可能會有一些細節,大致想的時候會被忽略。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 22:01
            @空明流轉
            好東西啊,好東西,看得我心花怒放~_~
            再次感謝~_~


            順便也感謝一下cexer。
            果然是【閱盡MFC,WTL,SmartWin++,win32gui,jlib2 ,VCF ;看盡天下 GUI 的感覺。】

            果然只看示例和書不寫代碼是不行的。就書上的示例代碼,我還領會不了其精髓……
            其實也不是我不想寫…… 我寫過一些……
            然后就沒機會寫了……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 21:47
            @空明流轉
            我靠!還有這種工具!
            太感謝了~_~

            其實我也不做什么的啦……
            主要是寫文檔(設計文檔、博客)的時候染染色啦……
            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 21:27
            @陳梓瀚(vczh)
            【子類不需要非得實現什么,純粹是模擬非純虛函數。因為父類必須提供所有可以覆蓋的界面的空實現,才可以讓實現控件的人,只寫他們關心的東西。】

            上面已經說明了:
            "父類提供所有可以覆蓋的界面的空實現",或者說默認實現,并讓實現控件的人,只寫他們關心的東西 —— 這不需要ATL-style式的繼承,普通繼承就可以了。

            只有在"向子類要求一些莫須有的東西"時,才需要依靠template。



            【我重寫VL++的目的就是想提供一個用來分析字符串(速度不用爆快,但肯定要好用)的庫。雖然不一定會實現一個C++的語法分析器(實際上我可以告訴你我沒法產生精確的語法樹,如果不做語義分析我肯定不知道a<b,c>d;究竟是什么東西),但上下文無關著色什么的肯定是可以輕松實現的。】
            編譯原理那些東西幾乎忘光……
            我覺得為編輯器著色有一個相對于編譯器來說很麻煩的地方……

            編譯器可以要求源代碼必須是合乎語法的,否則就報錯。
            編輯器的著色分析就不能這么暴力了,它必須能夠接受半完整的源代碼,并且盡可能從中榨取出信息……

            所以visual assistant還是很強大的……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 21:08
            @cexer
            有點感覺了。

            ATL-style繼承,一方面有點類類似concepts或者說ducking type的使用。
            template<class D>
            class B
            {
                    void f()
                    {
                            D* d = static_cast<B*>(this);
                            d->must_have_this_function(); // 必須有某個成員函數
                            d->must_have_this_variable;   // 必須有某個成員變量
                            typedef typename D::must_have_this_type type;
                            // 必須有某個嵌套類型
                    }
            };

            B可以對D提出一些要求,D必須滿足這些要求。
            對這些要求,B可以不必提供"默認實現"。
            這2點就是和普通繼承很不相同的地方了。


            同時,ATL并沒有通過"組合"來復用庫代碼,而是通過"共有實現繼承"來復用庫的代碼。
            使得編寫的代碼會少一些。 就像那個著名的例子:

            class person : public public nose, public mouth {};

            person p;
            p.eat(); mouth::eat
            p.smell(); nose::smell


            實際上呢,更"學術氣息"一些的方案是:
            class person
            {
                    nose n_;
                    mouth m_;
                    eye e_[2]; // left and right
            public:
                    // forwarding functions
                    void eat() { m_.eat(); }
                    void smell() { n_.smell(); }
            };


            但是在界面開發中……  這些轉發函數會寫死人的……
            所以,就產生了ATL-style繼承 —— concepts(ducking type) + 實現繼承的結合。


            只是為ATL-style繼承舉例的人的例子沒有選好,無法充分說明它的優點。
            我只粗看過《mfc程序員的wtl編程指南》還是什么的。
            里面就是一個"沒有體現出base對derived的需求",可以用普通繼承改寫的例子。


            這樣理解如何?


            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 20:37
            @cexer
            【你試試不用虛函數,不用ATL的這種編譯時的多態手法,在不知道子類為何物的情況下,在基類當中調用子類的方法試試? 】

            應該是不行的。

            只有template這種變態代碼生成器才可以:
            template<typename T>
            void f(T v)
            {
            v.f(); // 讓你先這么著了,等實例化的時候再做檢查……
            }

            如果不是模板,父類是不能調用子類函數的。

            那么,ATL-style繼承的作用就是:實現靜態的"template method"?

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 20:29
            @cexer
            你說的是這種情況么?

            non-template

            class B
            {
                    virtual void f_do() = 0;
                    void f()
                    {
                            ... // 有一些其他工作,不僅僅是轉發
                            f_do();
                            ...
                    }
            };

            B可以自己不實現f_do,并且具有這么一個限制:如果派生類不實現f_do,派生類將繼續無法實例化。


            ATL-style繼承,提供"類似"的含義。
            template<class D>
            class B
            {
                    void f()
                    {
                            ... // 有一些其他工作,不僅僅是轉發
                            static_cast<D*>(this)->f_do();
                            ...
                    }
            };

            class D : public B<D>
            {
                    void f_do() {  }
            }

            如果不實現f_do,D就會產生編譯錯誤。
            類似于如果上面那種D如果不定義f_do就無法實例化。



            普通繼承無法提供這種限制語意:
            class B
            {
                    void f()
                    {
                            ... // 有一些其他工作,不僅僅是轉發
                            f_do();
                            ...
                    }
                    // void f_do();
                    // 如果提供,派生類不不覆蓋也能實例化,也不會產生編譯錯誤。
                    // 無法達到限制"派生類必須提供"的目的

                    // 如果不提供,B就會產生鏈接錯誤。
            };

            是這樣嗎?

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 20:13
            @陳梓瀚(vczh)
            【header-only已經不錯了,我現在最煩一個類要將界面重復在兩個文件里面。】

            頭文件不行嗎?為什么會這樣?


            話說我想嘗試自己實現BOOST_ITERATE(只用宏復制代碼)的方法,最后研究了好久,發現用C的宏是不對的,應該自己制造代碼生成器……C的宏缺乏語法上的可維護性

            我也覺得宏很不可靠……
            有時候完全可以利用其他一些很方便的語言,來產生C/C++源代碼。
            憑借C/C++自身機制來進行元編程,有時候會很…… 很麻煩……

            比如boost.pp,它用來產生模板類型參數列表的這個功能,其實也可以寫一些其他語言的代碼,用來生成C++源代碼……

            可讀性應該會好很多……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 20:09
            @陳梓瀚(vczh)
            【其實我對語法最感興趣……因為我做編譯器……】
            能否做一個,呃,怎么說呢……

            visual assistant你肯定用的吧?類似的還有:
            msvc,gcc :
            synedit : http://synedit.sourceforge.net/
            scintilla : http://www.scintilla.org/
            還有一些C/C++源代碼轉換到html、pdf等格式的工具。

            它們肯定都能分析C/C++源代碼。
            但是源代碼分析后的結果,它們自產自銷了,沒有暴露出來。

            你能否做做這方面的工作呢? 一個C/C++(或者其他語言)的源代碼分析器,將分析的結果暴露出來。
            方便其他用途使用,比如代碼染色。

            這樣,很多編輯器、網頁、甚至是pdf、doc都可以得益于你的工作。
            而不是每個工具都自己實現一套(有的功能薄弱得……比如網頁上的染色,基本就只能認識語言的關鍵字而已),然后自產自銷。


            你覺得這個提議怎樣?

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 18:51
            @陳梓瀚(vczh)
            如何在屬性實現狀態變化控制的技術嘛,沒有說過命名……看來我們是互相誤解了啊…… 

            那你也說說你的想法嘛……
            比如那個“效率問題”應該怎么理解?

            有人說可以拿C/C++程序員作巴浦洛夫實驗,看提到"效率"2字時他們是否會流口水……

            我沒有流口水…… 但是我很好奇……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 18:39
            @cexer
            管飯的人呢……

            這問題反復困擾我很久了…… 一直沒得到解答…… 于是塵封了……
            用ATL/WTL的人很少,問都找不到人問……
            今天終于找到管飯的了, 一定得追問到底~_~

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 18:20
            @陳梓瀚(vczh)
            【如果你的庫不用dll+lib+h提供的話,請盡情使用模板】……

            如果ATL-style繼承的好處就是為了header-only。

            class Base
            {
                    void OnDraw() { /* inline */ }
            };

            或者:
            base.h
            class Base
            {
                    void OnDraw();
            };


            base.inl
            #include "base.h"

            inline void Base::OnDraw() {}


            也可以是header-only ……


            那么,ATL-style繼承,還有什么好處么……
            一開始,我也覺得很神奇…… 后來越想越不是那么回事…… 然后一直沒想通……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 18:16
            @陳梓瀚(vczh)
            @cexer

            我上面也說了, 這和普通的繼承實現的功能是完全一樣的。
            依然沒有虛函數開銷,依然有一點點"多態"。

            用vczh的例子來說:
            class Base
            {
                    void OnDraw() { 空 }
            };

            class Derived1 : public Base
            {
                    void OnDraw() { 我有新OnDraw }
            };

            class Derived2 : public Base
            {
            // 我用默認Draw
            };

            不也一樣嗎? 除了Base現在是一個類,而不是類模板。
            所以,我現在唯一想出的ATL-style繼承的優勢就是:header-only。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 18:06
            @陳梓瀚(vczh)
            屬性變化就是狀態變化嘛,你要監聽一個狀態的變化,還要控制一個狀態變化的權限,用屬性+事件的組合是很常見的。也就是說,一個屬性都要自動提供Changing和Changed兩個事件。嘗試把它做得高效,就是我之前的需求了。 

            這才是屬性的本質概念,跟語法什么的關系并不大。

            我覺得你又開始繼續扯遠了……
            本來不是在討論“proxy的實現技術”“property和命名函數”么……

            anyway,換個話題也好。
            不過我真沒看明白你的需求是怎樣的……

            這個需求是否高效,與“是否使用union”有關系嗎?
            與“property vs 命名函數”有關系嗎?
            是一個新話題吧?


            能詳細說說你的需求么?
            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 18:02
            @cexer
            ATL-style繼承,提供的語意是:
            基類提供默認實現,派生類繼并覆蓋自己需要的函數。
            是這樣嗎?
            除了這個,還有其他功能嗎?

            但這個功能,不正好就是非ATL-style繼承 —— 普通繼承提供的語意嗎……
            為什么要繞這么大一個圈子?
            能得到什么好處? header-only?

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 17:57
            @cexer
            絕沒問題,歡迎有自己思考的同志來此版聊,如果能切緊GUI框架的主題就感謝了哈,你們的討論能使我的博文增色不少。聊完不要走,此處管飯。

            別管飯了……  正好有一個懸了很久的關于ATL/WTL的疑問,你管管吧~_~

            是這樣的,ATL/WTL中提到一種atl-style繼承。
            template<typename D>
            class B
            {
                    void f1() { static_cast<D*>(this)->f1_do(); }
                    void f2() { static_cast<D*>(this)->f2_do(); }
                    void f1_do() { printf("B\n"); }
                    void f2_do() { printf("B\n"); }
                    
            };

            class D : public B<D>
            {
                    void f1_do() { printf("D\n"); }
            };

            D d;
            d.f1();
            D::f1不存在 -> 調用B::f1 -> 轉型為D* -> D覆蓋了f1_do -> 調用D::f1_do ->輸出"D"
            d.f2();
            D::f2不存在 -> 調用B::f1 -> 轉型為D* -> D::f2_do不存在 -> 調用B::f1_do->輸出"B"

            是這樣嗎?


            然后,問題就來了 …… 這個樣子,除了將代碼寫得更復雜以外,相比下面的寫法,有什么區別么??

            class B
            {
                    void f1() { printf("B\n"); }
                    void f2() { printf("B\n"); }
            };

            class D : public B
            {
                    void f1() { printf("D\n"); }
            };

            D d;
            d.f1(); "D"
            d.f2(); "B"


            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 17:43
            1:先做的事情寫在前面,后做的事情寫在后面,要花時間看清楚。 
            2:不要造成括號的嵌套,難以維護。 
            舉個例子,挑選列表里面所有偶數的數字然后平方,如果你寫成square(even(a_list))就不滿足1和2。 
            【注意,上面兩點你看過就算了,我不討論好跟不好,因為跟主題沒關系】

            不能算了……
            text.onchange_set( handler1 ).onchange_add( handler2 ).onchange_add( handler3 );
            滿足上面的2點嗎?


            對于你的點的例子,我傾向于CalculateRadius(your_point)。你不能否認人們總是下意識地認為獲取屬性比調用函數的效率要高,所以那些真的做了事情,又不改變狀態,又只讀的屬性變成函數比較好。
            點的例子是因為你說point不需要行為而舉出的反例。

            我也傾向于:
            point
            {
                    double x() const;
                    void x(double xx);
                    double r() const;
                    void r(double rr);
                    // ..
            };

            我也沒有假設get_r( p ); 和 p.r() 或者p.r到底何種效率更高。
            這取決與內部表達是直角坐標還是極坐標。

            這些都不是重點。重點在于:
            1. r絕對不可以是裸域 —— 它需要維護不變式
            2. 如果你打算將x、y、r、a由函數變為屬性,4個指針的開銷你覺得是否合適?

            btw:這4個屬性都可以是讀寫的,并不存在x、y讀寫,r、a只讀一說。


            不過我還是想跟你討論“在一個包含請求回調doing和響應回調one(+=也好,.Add也好)的屬性,怎么避免開銷”而不是在這里要不要用只讀的屬性。
            我沒看明白,能否再詳細一點?

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 17:23
            【我跟OwnWaterloo就借著你的地盤版聊了哈】

            要不我們開一個論壇吧?google groups或者群?
            群的聊天資料可能不容易搜出來……

            toplangauge越來越水了……

            把cppblog上的人都招集起來?

            很高興和你們討論問題~_~
            如果我語氣有過激之處,請不吝指出,或者多多包涵一下。

            有人響應沒……?

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 17:19
            【我并沒有反對你優化,我只是說“你覺得在一個【上百個】屬性的Form里面,你打算怎么處理屬性和事件之間的關系”。正好本篇是談GUI,因此舉這么個例子我覺得挺合適的。那我就這么問吧,我以為你是知道我在說什么的:在一個包含請求回調doing和響應回調one(+=也好,.Add也好)的屬性,怎么避免開銷?】

            首先,上百個屬性是否可以改為上百個×2的getter和setter?
            setter不一定難用,setter還可以鏈式表達呢。

            對比:
            1. w.p1(v1).p2(v2).p3(v3) ...
            2. ( (w.p1 = v1).p2 = v2 ).p3 = v3 ...
            3.
            w.p1 = v1;
            w.p2 = v2;
            w.p3 = v3;


            其次,如果真要模擬property。
            我真的沒看明白你說的那個需求是什么…… 囧


            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 17:11
            【行為指的是受改變的時候發生的事情,而不是你能從一個數據里面計算出什么東西。坐標轉換是映射,點在任何情況下都不可能因為你設置了一個什么坐標而做了一些什么事情,因此沒有行為。當然cache不同坐標系下的結果例外,這不是重點。】

            可能我們對“行為”這個詞有不同的理解。 那我們不用這個詞了。

            對剛才說的點的例子。半徑絕對不能直接讀寫對吧?
            所以必須將實現隱藏起來(實現可能是以直角坐標存儲), 通過setter/getter去操作,以維護點的不變式 —— 半徑不可能小于0。

            我說的就是這個意思。

            如果你需要可按極坐標操作的點,就不能直接暴露數據,必須使用setter/getter或者property。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 17:06
            【【窄化】不是問題。GUI是一個龐大的東西,一旦需要了,那就有做的必要,就算除了GUI以外的所有系統都不能從這個property機制上獲得好處,也不是不搞的理由。而且讓一個例子舉現在一個范圍里面可以讓我們都少想很多東西。】

            就算這種O(n)到O(1)的優化因為它太復雜而永遠用不上,【也不是不搞的理由】。
            我這么說對嗎?

            討論如何優化就是討論如何優化。
            沒有必要將這種討論限制到某個范圍內,然后說在這個范圍內不需要這種優化。

            你不能預見所有場合都不需要這種優化。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 17:01
            【至于其他的例子,你可以參考WPF強大的布局功能是怎么【under control】的,用傳統的方法根本沒法讓程序變得清晰。】

            我不懂wpf。
            不通過屬性,而是命名方法,可以做到讓程序清晰么?

            如果只是從:
            textBox.Text.OnChanging+=a_functor_that_want_to_check_the_input;

            變化到:
            textBox.Text.OnChanging.add( a_functor_that_want_to_check_the_input );
            textBox.Text.OnChangingSet( a_functor_that_want_to_check_the_input );
            textBox.Text.OnChangingAdd( a_functor_that_want_to_check_the_input );

            我覺得依然很清晰。
            也許前者對C#轉到C++的程序員來說,前者會很親切。
            但后者才是大部分C++程序員的每天都在使用形式。

            你不需要給你的用戶培訓“C++中如何模擬property”這種細節,他就可以使用你的api。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 16:56
            【其實舉過了嘛,textBox.Text.OnChanging+=a_functor_that_want_to_check_the_input;你覺得在一個【上百個】屬性的Form(你不要告訴我一個窗口的狀態很少)里面,你打算怎么處理屬性和事件之間的關系,我一直都在強調這一點,而不是語法上的問題,operator=其實也是個例子,我沒有強調說要不要有個名字之類的東西。 】

            textBox.Text.OnChanging+=a_functor_that_want_to_check_the_input;
            你覺得改成這樣,可接受不?
            textBox.Text.OnChanging.add( a_functor_that_want_to_check_the_input );
            textBox.Text.OnChangingSet( a_functor_that_want_to_check_the_input );
            textBox.Text.OnChangingAdd( a_functor_that_want_to_check_the_input );

            C++就是C++,沒有必要模擬.net那一套。


            【另外,不要覺得什么掉價不掉價的,技術沒有貴賤之分,不要搞三六九等。話說我自己在搞語言設計和實現。從來跟這些property什么的關系不大,這估計是職業病。】
            因為我覺得通過union來達到property的額外空間與property數量無關這個技巧可能是新奇的。我沒有在其他地方看到過,也是我自己想出來的。

            而proxy的那些技巧,我已經看太多,說不定大家都知道,我又何必多次一舉?
            而且很多都不是我獨立想出來的。
            所以我覺得說出來很掉價……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 16:42
            "當然這要看情況了。在我看來,每一個控件都要實現可監聽的屬性,這些屬性用事件暴露出來。你愿意設計完屬性之后從頭設計一次事件的命名和參數什么的好,還是愿意把它們綁定到屬性里面去?這樣的話開發控件也不需要考慮提供的事件完整不完整的問題了。因為控件的狀態都在屬性里面,屬性變更就是狀態變更,也就都有事件了。這樣做的話設計出來的控件就不會有winapi那個消息(我們都知道很難清洗化)的影子了,會有一個十分漂亮的設計出來。"

            消除winapi的影子,一定需要屬性嗎?命名函數不可以嗎?
            如果語言本身提供屬性,那使用兩者之一都沒什么問題。
            如果語言本身不提供,為何在可以使用命名函數的地方,非要去使用屬性???



            "一般winapi封裝出來的東西都是在PC上跑的,你會在意一個textbox占了1k還是1.1k內存嗎?在這里多一個指針少一個指針根本不是問題。 "
            在gui上,你的說法是正確的。你甚至可以使用boost::any + boost::tuple來得到一個類似python的開發方式。

            我討論的是"proxy得到object", 請不要將討論窄化gui上。
            作為一個庫(非gui庫)的提供者,效率不是最主要的,但無端的損害(大量損害)就是不可接受的了。
            假設某天你真的需要將proxy應用到critical的場景,你就會后悔當初沒有去考慮這個問題了。


            "特別是對于point,那就是個變量好了,point沒有行為,所以不需要屬性。"
            需要的。我舉個例子:
            point
            {
                    property double x { get;set; }
                    property double y { get;set; }
                    property double radius { get; set; }
                    property double seta { get; set; }
            };

            客戶可以用直角坐標或者極坐標去操作這個點。
            點的內部表示客戶無須關心。
            這樣的點,就需要行為。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 16:32
            "模擬屬性一點都不無聊,因為一個可以監聽和撤銷屬性變化的系統非常容易擴展,總比你一個類都來一個listener或者就像api一樣所有的消息的格式都很混亂的好。特別對于開發GUI的庫。當然這就不僅僅是如何響應operator=的問題了。允許阻止變化的listener總是有開銷的,所以你無法杜絕它。這也是我第一次舉例子的時候就說出來的一個可以認為是“需求”的東西。"

            模擬屬性就是很無聊的工作。
            你試著回答一個問題:”這里一定需要operator=嗎? 可以使用命名函數嗎?
            如果回答是“是” ,那這里就寧可采用命名函數,而不是屬性。
            絕大部分回答都應該是“是”。所以這根本不算一個需求。


            從我的直覺上來說,模擬屬性使用的價值并不大。沒有多少場合非屬性不可
            如果你可以想到一個“不是”的例子,請列舉出來。
            也許我的直覺是錯的。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 16:32
            "模擬屬性一點都不無聊,因為一個可以監聽和撤銷屬性變化的系統非常容易擴展,總比你一個類都來一個listener或者就像api一樣所有的消息的格式都很混亂的好。特別對于開發GUI的庫。當然這就不僅僅是如何響應operator=的問題了。允許阻止變化的listener總是有開銷的,所以你無法杜絕它。這也是我第一次舉例子的時候就說出來的一個可以認為是“需求”的東西。"

            模擬屬性就是很無聊的工作。
            你試著回答一個問題:”這里一定需要operator=嗎? 可以使用命名函數嗎?
            如果回答是“是” ,那這里就寧可采用命名函數,而不是屬性。
            絕大部分回答都應該是“是”。所以這根本不算一個需求。


            從我的直覺上來說,模擬屬性使用的價值并不大。沒有多少場合非屬性不可
            如果你可以想到一個“不是”的例子,請列舉出來。
            也許我的直覺是錯的。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 16:27
            "舉個簡單的例子,總線形式的開發會讓string有一個c_str(),而不是讓string消失。我不知道你知不知道解決方案是什么樣子的,但是舉個例子出來總是要告訴別人說,“哦,這個東西可以這么這么做,只是我懶的寫完整”而不是沒說完。"

            我相信看的人能明白我代碼中的重點在那里。
            我不明白的是你為何看不明白,即使在我說了之后。

            我再說一下吧,如果要讓我說"這個property"還可以這樣玩、又可以那樣玩,我會覺得很掉價……
            一方面因為我現在本來就不喜歡過分玩弄語言特性。
            另一方面,這些技術實在是說得太多……


            如果一定要把所有細節都展現出來,不知道評論的字數會不會夠。
            而且,展現到什么程度才可以停止?

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 16:15
            @陳梓瀚(vczh) "在關心程序的質量的同時,也要同時關心一下如何將廣大程序猿在C++的水深火熱之中解放出來" 我展示的,只是"proxy得到object"的技術。 你可以繼續展示proxy得到object之后的"解救廣大C++程序員于水深火熱之中"的其他技術。 但說實話,我不覺得那些技術真的能救人于水火
            真正救人于水火的,不是玩弄高級技巧,而是設計清晰的接口。
            還是上面的例子: C c; C2 c2; c.f( c2.i ); 不能這樣做,只會讓人感到困擾。 如果i不是屬性,而是成員: c.f( c2.i() ); 不行是很容易理解事情 —— 臨時對象不能綁定到非const引用上。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 16:07
            @陳梓瀚(vczh)
            "不過用了union,而跟你剛才那樣一個屬性就要定義一個類,而不是一種類型的屬性定義一個類(或者干脆就只有少數幾個屬性的類然后到處使用——這個要求比較高了一點),我覺得比多一個指針更加不能接受。運行時代價跟開發代價都是需要一并考慮的。"

            先說運行代價和開發代價。
            C程序員可能會因為效率,不使用qsort。 他們都是傻子嗎?

            "實現屬性占用的額外空間大小與屬性的數量無關",這難道真的不值得你為其多花點功夫嗎?
            這是O(n)到O(1)的優化!是不值得的?!


            而且我比較懷疑你所說的"一種類型的屬性定義一個類"是一種[color=red]侵入式[/color]的實現方式。


            需要實現屬性的類本來就不應該很多。
            我也想如何做得更范化一些, 但目前成效不大。

            就像cexer說的"高效的,不會制造麻煩的東西,也是從不高效的,會制造麻煩的東西進化來的。"
            如果一開始就采用指針保存,那是一輩子就沒辦法優化了。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 15:59
            @陳梓瀚(vczh)
            "如果別人解決了一個帶多余指針的好用的屬性,你解決了一個不帶多余指針的不好用的屬性,那都是沒意義的。"

            我那個是沒有意義的?
            我那個不可以繼續實現你所說的那些花哨的用法嗎?(為什么說花哨,我下面會說明)

            我已經說過很多次了,"通過proxy得到被proxy的對象"是實現proxy的前提。
            必須先滿足這個前提才能繼續實現proxy的其他技巧。

            用union會影響實現其他技巧嗎? 依然可以。
            難道我要把所有我會的技巧都展現一下嗎?
            我不喜歡這樣[color=red]顯擺[/color]。
            或者說,我也喜歡顯擺;但[b]我不喜歡顯擺[color=red]眾人皆會[/color]的技巧[/b]。
            分享一些別人明顯了解的技術,只會[b][color=red]漲[/color]別人眼睛[/b]。


            我只想展示如何高效實現proxy所需前提這一技巧,如是而已。



            btw:為什么我說你那些是花哨的技巧。

            首先引入一個概念:"總線式的設計"。

            假設你需要實現一個函數f,f需要一個字符串輸入(暫不考慮wchar_t)。
            如何設計這個輸入參數???

            1. f(const char* c_style_string);
            2. f(const char* first,ptrdiff_t length);

            兩者取其一,可能1用得更多一些。

            然后,其他所有的String,都向這個"總線" —— const char*靠攏。
            比如std::basic_string要提供c_str(), CString要提供operator const char*()。

            為什么要這么做?
            1. 避免API的暴增。 直連線是平方增長,而總線是線性增長。
            2. 有些時候,必須這樣
            對fopen(const char*)你可以繼續直連線:
            fopen(const std::string& );
            fopen(const CString& );

            對一個類:
            class C {
            open(const char* );
            };

            C不是你寫的,你不可能為C加入一個直連線。
            你只能繞彎:
            open( C& o, const std::string& );
            open( C& o, const CStirng& );


            回到你說的ref<T>。

            假設有一個函數:
            f(int& );
            你可以為它直連線。


            假設有一個類,依然不是你寫的,它只接受int &
            class C
            {
            f(int & );
            }

            C2有一個屬性i。
            class C2
            {
            property int i;
            }

            你要怎么給你的用戶解釋:
            C c;
            C2 c2;
            c.f( c2.i ); 是行不通的,必須
            f( c, c2.i ); ???

            你能將所有api的匯合點都直連線嗎? 你做不到。


            本來模擬屬性就是一個很無聊的事情了。
            你告訴用戶,這就是一個C#中的 get; set; 就ok了,別想著要其他怎么用。
            C#中可以 &o.p嗎???



            "運行時代價跟開發代價都是需要一并考慮的。"
            你看你是否自相矛盾了。
            將線性開發代價的總線形式,轉化為平方開發代價的直連線形式。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 14:02
            @cexer
            我再想想如何做得更范化一些。
            減少需要編寫property的人的重復勞動。

            但是遇到了困難……

            手工寫union base, union member沒什么問題。
            要將其做成模板…… 會遇到先有雞還是先有蛋的問題……

            比如:
            proxy< ..., getter , ... >

            實例化一個property:
            proxy< ..., &date::get_second, ... >; 這里需要date的定義?

            而date的定義無論是union base,union member又需要先實例化proxy< ... &date::get_second, ... >;……
            很囧……


            手工寫沒問題是因為:
            struct second_proxy {
            這里僅僅聲明其布局就可以了
            };

            然后定義date類

            然后實現proxy::op ...
            這里才需要引用到date::&getter


            我再想想……


            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 13:50
            @陳梓瀚(vczh)
            1.
            如果一個property需要消耗一個指針的代價,我認為實現得再好用都是不可接受的…… 高得有點離譜。
            很容易一個類的property的消耗比類本身還要高。
            [data of instance]
            [pointer]
            [pointer]
            [pointer]
            [pointer]
            ....
            而且所有pointer都指向同一個地方……

            而且上面也提到,真正需要模擬出property的,是類似于point、vector、matrix這種類。
            p.x比p.x()更自然。
            讓這種類附加額外數據,也是讓人很難接受的。


            2.
            是否好用,你可以另外開文章討論。
            只是你提到的那些使得proxy好用的技術,都提不起我的興趣。
            理由很簡單 —— 這種文章太多,寫出來都不好意思和人打招呼。

            我關心的僅僅是proxy如何高效得到被proxy對象 —— 實現proxy的前提。

            我以前見過的,包括我自己想到的,都是上面one property one pointer的方案。imp cpp中提到的讓我確實有眼前一亮的感覺。
            而 op T(), op= (T), ref T op + 這些技術,只讓我覺得漲眼睛 —— 看太多,早膩歪了。


            如果你的重點依然在proxy如何更仿真上,可能很難提起我的興趣。
            如果你有興趣思考proxy如何得到被proxy的object上,或者有一些方案,想法,歡迎分享出來~_~



            "當且僅當好用,才有繼續考慮有沒有消耗的必要。一個高效的、會制造麻煩的解決方案一般是不被接受的。"
            這句話絕對說得過于絕對了。
            如果你用的是C++、而不是C#,效率絕對不是可以不掛在心上的事情。
            為什么你要用C++,而不是用編程更方便,語法糖更多的C#?好好想想吧。

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 13:19
            @陳梓瀚(vczh)
            還是用代碼說話吧……

            上面的date的代碼,重點在于這2行:
            union { /* ... */ };

            哦,還有一行在我的測試代碼中,并沒有抄出來:
            typedef int assume[sizeof(date)==sizeof(time_t)?1:-1];
            這2行才是我想表達的重點 —— 沒有額外的空間消耗,實現property。


            寫上面那些代碼,為的是展示上面那個重點,而不是下面這種爛大街的:
            operator = (int);
            operator int() const;
            這些技術早就被人討論得七七八八了,相當無聊……


            這一點不知道你看出來了沒?
            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 13:12
            @陳梓瀚(vczh)
            我在上面的評論也說了,在C++中沒有絕對必要,還是不要模擬這個東西了。
            沒有property,生活一樣可以繼續。


            至于 o.p1 + p.p2, &p.p1, 等模擬,并不是重點。
            proxy本來就和被proxy的對象有所區別。
            視你需要模擬的程度來決定編程的復雜度,或者發現某種特性無法實現。

            proxy的重點在于如何高效的在proxy中得到被proxy對象。
            實現了這個功能點,才是其他op=,op T(), op +, ref proxy的前提 —— 這些技術基本屬于濫大街了 —— 去看vector<bool> —— 所以我對這些沒什么興趣。

            之所以重新開始研究這個技巧,是因為Imperfect C++中提到了一種代價很低的方案。
            我覺得這個有點意思,所以繼續深入了一下。
            re: SFINEA in C++ OwnWaterloo 2009-11-16 03:58
            @唐風
            我試試 …… 謝謝~_~

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-16 02:48
            關于隱藏time_成員……
             
            1.
            class C
            {
            public:
                    union
                    {
                            proxy1 property1;
                            proxy2 property2;
                            proxy3 property3;
                            // private: // msvc和gcc這里是不能加入private的(具體要查標準)
                    }
            };
             
             
            2.
            class C
            {
            public:
                    union
                    {
                            proxy1 property1;
                            proxy2 property2;
                            proxy3 property3;
                    }
            private:
                    struct impl impl_; // 一旦不放在union中
                    // properties就可能會被填充
            };
             
             
            仔細選擇union的位置,可能會起到減少總大小的效果,比如:
            class C1 {
                    char c_;
            public:
                    union { /* properties */ };
            private:
                    int i_;
            };
            class C2 {
                    int i_;
                    char c_;
            public:
                    union { /* properties */ };
            };
             
            因為char c_;的附近本來就會被填充,properties剛好占據那個位置。
             
             
            如果這樣,就可能會很糟糕:
            class C3 {
                    char c_;
                    int i_;
            public:
                    union { /* properties */ };
            };
             
            C++標準沒有說class的layout應該怎么安排。
            每個access secion中的data,必須按聲明順序。
            但不同access secion之間,可以打亂順序 —— 這個也許會有一些幫助。
             
            第2種方案依然需要計算offsetof…… 這是很不靠譜的……
             
             
            3.
            作為base。
             
            struct properties
            {
                    union
                    {
                            proxy1 property1;
                            proxy2 property2;
                            proxy3 property3;
                            // ...
                    }
            };
             
            class C : public properties
            {
                    // data
            };
             
            這樣,可以很容易計算出C的位置:
            void property_proxy::operator=( ... ) {
                    void* p = this;
                    C* c = static_cast<C*>( static_cast<properties*>(p) );
            }
             
            編譯器會正確計算出C*,即使在多繼承下也行。比如:
            class C : other , public properties {};
             
            但是,在msvc和gcc上,properties 都不會執行空基類優化…… 很囧……
            仔細安排data的布局(在這2款編譯器上,將小對齊的數據放前面),也會影響整個類的大小。
             
             
            2和3的方案,如果能鉆到空子,就可以幾乎沒有代價的實現property。
            空子就是說,那個class本來就有一些需要被填充的空洞……
             
            如果沒有空可鉆……  或者沒有正確安排位置…… 會多占用一些大小。
            額外大小不超過class中所有域中需要最大對齊那個成員的大小。
            額外大小和properties的數量是無關的, 多少個properties都占用這么多額外大小, union嘛……
             
             
            4.
            還有一種方案。
            其實上面的date,缺陷在于time_t time_; 這個成員會被外界訪問。
             
            可以這樣:
            class date {
                    class impl {
                            time_t time_;
                            friend class date;
                    };
            public:
                    union
                    {
                            impl impl_;
                            proxy1 property1;
                            proxy2 property2;
                            proxy3 property3;
                    }
                    // ...
            };
             
            這樣,客戶代碼可以訪問的,只有impl_這個名字。
            但是幾乎不能拿它作任何事情。
            連它的類型名 —— date::impl —— 都是不可訪問的。
             
             
            這個方案的缺陷就是 —— 通常必須從頭設計一個類型。
            union中不能放非pod。只能從內建類型開始,構造一些類。
             
            比如已經有某個非pod的類,C,想將C作為一個成員,實現Cex:
             
            class Cex
            {
                    union
                    {
                            C impl_; // 不行
                    }
            };
             
            只能用上面的property base或者property member……
             
             
            5.
            范化工作 
            這個…… 再說吧……
             如果能有更好的布局方案…… 范化工作就白做了……
             
            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 22:33
            @cexer
            關鍵點在于:"如何通過proxy地址,得到object地址"。
             
            1. 可以給proxy放入一個object的指針。每個proxy消耗一個指針的空間。
            太浪費了……
             
            2. Imperfect C++中利用offset來計算object的地址,使得每個proxy不含任何域。
            但C++為了區別各個proxy,會給每個proxy進行填充,依然會造成消耗。
             
             
            3. 避免proxy在Record中被填充
            假設有如下記錄:
            Record
            {
                    proxy1 property1;
                    proxy2 property2;
                    proxy3 property3;
                    ...
            }
            其中proxy1,proxy2,proxy3, ...  是空結構。
             
            Record r;
            r.property1;
            r.property2;
            r.property3;
            ...
             
            在C/C++中,如果想要property1、2、3、... 不占空間,也就是它們必須擁有相同的地址。
            也就是說…… Record 是union……
             
             
            4. 避免Record在class中被填充
            即使這樣,整個union依然是會被填充……
            所以,可以將class的數據和union放在一起,就真的不消耗任何空間了……
            (如果類本身不需要數據,那這個類也是會被填充的,proxys依然沒有消耗多余的空間)
             
             
            代碼:
            class date
            {
            private:
                    
            struct second_proxy
                    {
                            
            operator int() const
                            {
                                    
            const void* o = this;
                                    
            int sec = static_cast<const date*>(o)->get_second();
                                    printf(
            "%d second_proxy::operator int(%p);\n",sec,o);
                                    
            return sec;
                            }
                            date
            & operator=(int sec)
                            {
                                    
            void* o = this;
                                    printf(
            "second_proxy::operator=(%p,%d);\n",o,sec);
                                    date
            * d = static_cast<date*>(o);
                                    d
            ->set_second(sec);
                                    
            return *d;
                            }
                    };

            public:
                    union
                    {
                            time_t time_;
                            second_proxy second;
                    };

                    date()
                    {
                            printf(
            "date::date(%p);\n",(void*)this);
                            time(
            &time_);
                    }

                    
            int get_second() const
                    {
                            
            int sec = localtime(&time_)->tm_sec;
                            printf(
            "%d date::get_second(%p);\n",sec,(void*)this);
                            
            return sec;
                    }

                    
            void set_second(int sec)
                    {
                            printf(
            "date::set_second(%p,%d);\n",(void*)this,sec);
                            tm t 
            = *localtime(&time_);
                            t.tm_sec 
            = sec;
                            time_ 
            = mktime(&t);
                    }
            };

            second_proxy hour和date的數據time_t time_放在同一個union中。
            這樣,它們擁有相同的地址。
            在second_proxy::operator int() const; 中,可以直接將this轉換到const date* ……
            就這樣得到了…… object的地址……
             
             
            在C中,必須給那個union取一個名字:
            struct date
            {
                    union
                    {
                            time_t time_;
                            second_proxy second;
                    } must_have_a_name;
            };
            struct date date;
            date.must_have_a_name.second; 必須這樣訪問……
             
            C++中有匿名聯合,所以可以直接:
            date d;
            d.second;
             
             
            這樣的壞處也很明顯……
            客戶代碼可以訪問 d.time_;   什么都完蛋了……
             
             
            我再想想怎么隱藏……
             
            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 22:02
            @cexer
            我想到一個幾乎沒有消耗的方案……
            我再完善一下……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 20:31
            @cexer
            Imperfect C++中的差不多看明白了……
            proxy是包含在object中,通過proxy在object中的offset得到object的地址……


            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 19:57
            我暈……
            侵入式的property……

            強大……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 19:43
            我去看了看Imperfect C++。因為是英文的,以前只看了一部分就停了……
            我覺得前面都寫得不錯,ABI、mangling這些問題確實是很困擾……

            但property…… 我覺得這并不算C++的Imperfection。
            完全是被其他語言給蒙蔽了。

            一門語言就應該有一門語言的樣子。
            比如用C,如無絕對必要,就不應該模擬出虛函數與異常機制。
            書里面提到的7種優勢,除了最后一種值得考慮,其他全都不值得稱作優勢。

            property,C#中的,或者imperfect cpp 里面看起來的樣子,無非就是讓如下語法:
            o.p( value ); o.set_p( value );
            value = o.p(); value = o.get_p();

            變成如下語法:
            o.p = value;
            value = o.p;

            如果C++直接提供property的語法,那當然是好事。
            但不提供,也不見得編程就進行不下去了,也沒有絕對必要去模擬出這種東西。


            書中提到的7個好處,除了最后1個,其他都不是property帶來的好處。

            1. 讀寫控制
            非property一樣可以實現讀寫控制

            2. 內外表示轉換
            這依然是由Date的算法實現,而不是property的功勞。
            不通過property,一樣可以實現time_t作為內部表示,對外提供int get_xxx()

            3. 驗證
            這個更搞笑了。
            就在書中這句話的下面列出的代碼,就明顯說明對day的驗證是通過:
            void Date::set_DayOfMonth(int day);
            完成的。

            完全沒有property的半分功勞。

            4. 沒看太明白
            書中的意思是, Date.Now是一個緩存,Date::get_Now()是一個計算?
            其實,這里真正需要的是"兩種語意",而不是property。
            這兩種語意是:
            Date::getNow();
            Date::updateNow();

            書中只是將getNow的語意,用property來表現;get_Now同時完成updateNow和getNow。


            5. 可用性?
            We didn't have to write date.get_Month(), just date.Month.
            少敲點鍵盤而已……
            如果利用重載,用void Month(value)代表set,用value Month(void)代表get,少敲的,就是一個調用操作符……

            6. 不變式?
            沒看太明白。
            沒有property,也可以維護object的不變式,是吧?
            只要將數據hide,通過public interface去操作,就可以了。

            7. 范型編程
            我覺得就只有這個說到點子上了。 而這個也就是模擬property的真正的作用:改變語法。
            template<typename P>
            void distance(const P& p1, const P& p2 ) {
            假設這是一個計算2個點歐式距離的函數。 它已經通過:
            p1.x;
            這種語法,而不是p1.x(); 這種語法寫成了。
            }

            如果新實現一個class, 想通過p1.x 這種語法訪問,同時還要有讀寫控制等, 就需要模擬出property。
            這可能是property真正的用處。




            換句話說,真的存在很多情況,使得我們"不得不"使用如下語法:
            o.p = value;
            value = o.p;

            來代替如下語法:
            o.set_p( value );
            value = o.get_p();
            嗎?

            對這種情況,property模擬才是有價值的。


            對很多情況,setter/getter的語法和property的語法都是可行的。
            如果本身提供了property語法的語言,那使用2者之一都沒關系。
            但C++沒有提供。對這種情況也非要去模擬出property的語法,就有點…… 為了property而property的味道了。


            我繼續去看書中怎么實現的……
            我以前了解的實現方式,每一個proxy至少得帶一個指針……
            這消耗還是蠻嚴重的……


            你怎么看?
            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 18:58
            @cexer
            沒有完整的,就是你blog上發的一些片段……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 18:57
            @cexer
            哦 原來是property模擬。

            window.size
            window.onCreated
            是一個,呃,代理(proxy)對象?

            size是一個代理,有一個=操作符和轉換函數:
            operator=(const Size& s) {
            this->window->setSize(s);
            }
            operator Size() const {
            return this->window->getSize();
            }

            這個代理對象也是要占空間的吧?


            呃…… 還是等你的源代碼與分析吧…… 不瞎猜了……
            看來你也是難得抓到一個更新blog的閑暇……

            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 18:40
            從這2行代碼來說:
            window.onCreated.add( &_handleCreated );
            window.onCreated.clear();


            從UINT message 到 onCreate 的這個分派(dispatch)過程,無論怎樣都必定是一個運行時解析過程。
            無論使用何種C++高級技巧,也不可能讓它變為編譯時dispatch。
            因為message是一個運行時才能得到的值……
            只是,這個dispatch的工作,可能不是由window所在的class完成,而是其他某個層次完成。
            總之,這個層次一定存在,這個工作(運行時dispatch)一定免不了。
            我猜得對嗎……


            接下來,框架將message 分派到onXXX之后,客戶再將onXXX轉發(forwarding)自己的handler這個過程,我相信是可以編譯時確定的。
            ——因為我看過你以前的一些實現~_~

            但是,編譯時確定,就意味著運行時不可更改。
            如果要運行時可更改 —— 如上面2行代碼 —— 就一定需要一個"可調用體"(callable)來作handler的占位符(placeholder)。
            是這樣嗎?
            而C/C++里面,完全不占用一點空間的callable…… 是不存在的,對吧?


            所以我很好奇window是如何零成本完成映射與轉發,并且是一個空對象的。
            映射肯定需要在某個地方做,可能不是window。
            運行時可更改轉發目的地而不使用數據, 好像…… 太不可思議了……


            re: GUI框架:談談框架,寫寫代碼 OwnWaterloo 2009-11-15 18:21
            占個沙發,對這個很好奇:

            "值得說一下,這種神奇的映射者是接近零成本的,它沒有數據成員沒有虛函數什么都沒有,就是一個簡單的空對象。就像傳說中的工作能力超強,但卻不拿工資,不泡公司MM,甚至午間盒飯也不要的理想職員。"

            沒辦法…… 讓它吃點虧好了:
            template <typename DataStream>
            DataStream& operator>>(DataStream& a_data, A& a_fileHeader);

            該成這樣:
            template<typename C,class T>
            std::basic_istream<C,T>& operator>>(std::basic_istream<C,T>& s,A& a);

            這也是為iostream寫擴展時要考慮的一個問題:
            1. 要么嚴格使用標準庫中的(w)i(f/string)stream,basic_i(f/string)stream
            2. 要么放寬,使用任意重載了>>的。



            二進制和文本關系到是否轉換換行模式。

            寫入文件時是怎么寫的?
            >>和<<是格式化輸出。
            read/write是非格式化輸出。
            12
            <<結果就是 '1','2' , >>時也希望是這樣
            write結果就是 0c,00,00,00, read時也希望是這樣。

            re: 函數調用棧初探 OwnWaterloo 2009-11-15 03:33
            調試器需要符號表。

            re: Concept 被移除,無緣 C++ 0x OwnWaterloo 2009-11-15 02:34
            依然可以算C++0x……
            0x嘛,大家都知道是16進制……
            明年是C++0a,后年是C++0b ...

            re: SFINEA in C++ OwnWaterloo 2009-11-15 02:33
            現在和cnblogs的格式很相似了。
            Windows Live Wirter可以導入pdf,然后發布到blog么?

            或者Windows Live Writer在本地使用的什么格式? 可以diff(主要目的)么……

            我有個想法是用某種文本文件格式的代碼,比如html,latex,rst等,生成可以導入到Windows Live Writer的格式,再發布。
            文本格式的代碼可以diff……

            共10頁: First 2 3 4 5 6 7 8 9 10 
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(8)

            隨筆檔案(16)

            鏈接

            搜索

            •  

            積分與排名

            • 積分 - 197925
            • 排名 - 133

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            久久久人妻精品无码一区 | 无码专区久久综合久中文字幕| 久久这里只有精品视频99| 亚洲精品无码久久久| 无遮挡粉嫩小泬久久久久久久| 国产精品久久精品| 女人高潮久久久叫人喷水| 精品综合久久久久久888蜜芽| 久久久91精品国产一区二区三区| 久久久久无码精品国产app| 久久夜色精品国产网站| 久久久WWW成人| 99久久国产综合精品麻豆| 久久只这里是精品66| a级毛片无码兔费真人久久| 一本久道久久综合狠狠爱| 久久精品国产清自在天天线| 久久久无码精品亚洲日韩按摩| 久久AAAA片一区二区| 久久婷婷久久一区二区三区| 久久亚洲AV无码精品色午夜| 国产精品无码久久四虎| 国内精品久久人妻互换| 波多野结衣久久| 久久99精品久久久久久不卡| 99热成人精品热久久669| 久久综合狠狠综合久久综合88| 99久久免费国产精品特黄| 久久综合久久鬼色| 久久99久久无码毛片一区二区| 91性高湖久久久久| 国产午夜久久影院| 国产一区二区三区久久| 久久99国产精品久久| 99久久成人国产精品免费| 久久精品中文闷骚内射| 精品国产VA久久久久久久冰| 国产精品美女久久久久网| 久久久久久狠狠丁香| 久久亚洲精品视频| 久久久久亚洲精品天堂久久久久久|