青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

longshanks

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  14 Posts :: 0 Stories :: 214 Comments :: 0 Trackbacks

常用鏈接

留言簿(10)

我參與的團(tuán)隊(duì)

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

GP技術(shù)的展望——先有鴻鈞后有天

莫華楓


    自從高級(jí)語言出現(xiàn)以來,類型始終是語言的核心。幾乎所有語言特性都要以類型作為先決條件。類型猶如天地,先于萬物而存在。但是,是否還有什么東西比類型更加原始,更加本質(zhì),而先于它存在呢?請(qǐng)往下看。:)

泛型和類型

    泛型最簡(jiǎn)短最直觀的描述恐怕應(yīng)該是:the class of type。盡管這樣的描述不算最完備,但也足以說明問題。早在60年代,泛型的概念便已經(jīng)出現(xiàn)。最初以“參數(shù)化類型”的名義存在。70年代末期發(fā)展起來的 恐龍級(jí)的Ada(我的意思不是說Augusta Ada Byron Lovelace伯爵夫人是恐龍,從畫像上看,這位程序員的祖師奶長(zhǎng)得相當(dāng)漂亮:)),尚未擁有oop(Ada83),便已經(jīng)實(shí)現(xiàn)了泛型(Generic)。盡管泛型歷史悠久,但真正全面地發(fā)展起來,還是在90年代初, 天才的Alexander A. Stepanov創(chuàng)建了stl,促使了“泛型編程”(Generic Programming)的確立。
    出于簡(jiǎn)便的目的,我套用一個(gè)老掉牙的“通用容器”來解釋泛型的概念。(就算我敷衍吧:P,畢竟重頭戲在后面,具體的請(qǐng)看前面給出的鏈接)。假設(shè)我在編程時(shí)需要一個(gè)int類型的棧,于是我做了一個(gè)類實(shí)現(xiàn)這個(gè)棧:
    class IntStack {...};
    用的很好。過了兩天,我又需要一個(gè)棧,但是類型變成了double。于是,我再另寫一個(gè):
    class DoubleStack {...};
    不得了,好象是通了馬蜂窩,不斷地出現(xiàn)了各種類型的棧的需求,有string的,有datetime的,有point的,甚至還有一個(gè)Dialog的。每 種類型都得寫一個(gè)類,而且每次代碼幾乎一樣,只是所涉及的類型不同而已。于是,我就熱切地期望出現(xiàn)一種東西,它只是一個(gè)代碼的框架,實(shí)現(xiàn)了stack的所 有功能,只是把類型空著。等哪天我需要了,把新的類型填進(jìn)去,便得到一個(gè)新的stack類。
    這便是泛型。
    但是,僅僅這些,還不足以成就GP的威名。
    我有一個(gè)古怪的需求(呵呵,繼續(xù)敷衍。:)):
    做一個(gè)模板,內(nèi)部有一個(gè)vector<>成員:
    template<typename T> A
    {
        ...
        vector<T> m_x;
    };
    可是,如果類型實(shí)參是int類型的話,就得用set<>。為了使用的方便,模板名還得是A。于是,我們就得使用下面的技巧:
    template<> A<int>
    {
        ...
        set<T> m_x;
    };
    這叫特化(specialization),相當(dāng)于告訴編譯器如果類型實(shí)參是int,用后面那個(gè)。否則,用前面的。特化實(shí)際上就是根據(jù)類型實(shí)參由編譯器執(zhí)行模板的選擇。換句話說,特化是一種編譯期分派技術(shù)。
    這里還有另一個(gè)更古怪需求:如果類型實(shí)參是指針的話,就用list<>。這就得用到另一種特化了:
    template<typename T> A<T*>
    {
        ...
        list<T> m_x;
    }
    這是局部特化(partial specialization),而前面的那種叫做顯式特化(explicit specialization),也叫全特化。局部特化則是根據(jù)類型實(shí)參的特征(或者分類)執(zhí)行的模板選擇。
    最后,還有一個(gè)最古怪的需求:如果類型實(shí)參擁有形如void func(int a)成員函數(shù)的類型,那么就使用deque。這個(gè)...,有點(diǎn)難。現(xiàn)有的C++編譯器,是無法滿足這個(gè)要求的。不過希望還是有的,在未來的新版C++09中,我們便可以解決這個(gè)問題。

Concept和類型

    concept是GP發(fā)展必然結(jié)果。正如前面所提到的需求,我們有時(shí)候會(huì)需要編譯器能夠鑒識(shí)出類型的某些特征,比如擁有特定的成員等等,然后執(zhí)行某種操作。下面是一個(gè)最常用的例子:
    swap()是一個(gè)非常有用的函數(shù)模板,它可以交換兩個(gè)對(duì)象的內(nèi)容,這是swap手法的基礎(chǔ)。swap()的基本定義差不多是這樣:
    template<typename T> swap(T& lhs, T& rhs) {
        T tmp(lhs);
        lhs=rhs;
        rhs=tmp;
    }
    但是,如果需要交換的對(duì)象是容器之類的大型對(duì)象,那么這個(gè)swap()的性能會(huì)很差。因?yàn)樗鼒?zhí)行了三次復(fù)制,這往往是O(n)的。標(biāo)準(zhǔn)容器都提供了一個(gè) swap成員函數(shù),通過交換容器內(nèi)指向數(shù)據(jù)緩沖的指針,獲得O(1)的性能。因此,swap()成員是首選使用的。但是,這就需要程序員識(shí)別對(duì)象是否存在 swap成員,然后加以調(diào)用。如果swap()函數(shù)能夠自動(dòng)識(shí)別對(duì)象是否存在swap成員,那么就可以方便很多。如果有swap成員,就調(diào)用成員,否則, 就是用上述通過中間變量交換的版本。
    這就需要用到concept技術(shù)了:
    template<Swappable T> void swap(T& lhs, T& rhs) {
        lhs.swap(rhs);
    }
    這里,Swappable是一個(gè)concept:
    concept Swappable<typename T> {
        void T::swap(T&);
    }
    于是,如果遇到擁有swap成員函數(shù)的對(duì)象,正好符合Swappable concept,編譯器可以使用第二個(gè)版本,在O(1)復(fù)雜度內(nèi)完成交換。否則,便使用前一個(gè)版本:
    vector a, b;
    ... //初始化a和b
    swap(a,b); //使用后一個(gè)版本
    int c=10, d=23;
    swap(c, d); //使用前一個(gè)版本
    這里的swap()也是運(yùn)用了特化,所不同的是在concept的指導(dǎo)下進(jìn)行的。這樣的特化有時(shí)也被稱作concept based overload。
    從上面的例子中可以看到,原先的特化,無論是全特化,還是局部特化,要么特化一個(gè)類型,要么特化一個(gè)大類(如指針)的類型。但無法做到更加精細(xì)。比如,我 希望一個(gè)模板能夠針對(duì)所有的整數(shù)(int,long,short,char等)進(jìn)行特化,這在原先是無法做到的。但擁有了concept之后,我們便可以 定義一個(gè)代表所有整數(shù)的concept,然后使用這個(gè)整數(shù)concept執(zhí)行特化。換句話說,concept使得特化更加精細(xì)了,整個(gè)泛型系統(tǒng)從原來“離 散”的變成了“連續(xù)”的。
    不過上面那個(gè)concept特化的模板看起來實(shí)在不算好看,頭上那一坨template...實(shí)在有礙觀瞻。既然是concept based overload,那么何不直接使用重載的形式,而不必再帶上累贅的template<...>:
    void fun(anytype a){...} //#1,anytype是偽造的關(guān)鍵字,表示所有類型。這東西最好少用。
    void fun(Integers a){...} //#2,Integers是concept,表示所有整型類型
    void fun(Floats a){...} //#3,F(xiàn)loats是concept,表示所有浮點(diǎn)類型
    void fun(long a){...} //#4
    void fun(int a){...} //#5
    void fun(double a){...} //#6
    ...
    int x=1;
    long y=10;
    short z=7;
    string s="aaa";
    float t=23.4;
    fun(x); //選擇#5
    fun(y); //選擇#4
    fun(z); //選擇#2
    fun(s); //選擇#1
    fun(t); //選擇#3
    這種形式在語義上與原來的模板形式幾乎一樣。注意,是幾乎。如下的情形是重載形式無法做到的:
    template<Integers T> T swap(T lhs, T rhs) {
        T temp(lhs);
        ...
    }
    這里,模板做到了兩件事:其一,模板萃取出類型T,在函數(shù)體中,可以使用T執(zhí)行一些操作,比如上述代碼中的臨時(shí)對(duì)象temp的構(gòu)造。這個(gè)問題容易解決,因?yàn)檩腿☆愋蚑還有其他的方法,一個(gè)typeof()操作符便可實(shí)現(xiàn):
    Integers swap(Integers lhs, Integers rhs) {
        typeof(lhs) temp(lhs);
        ...
    }
    其二,模板保證了lhs,rhs和返回值都是同一類型。這個(gè)問題,可以通過施加在函數(shù)上的concept約束解決:
    Integers swap(Integers lhs, Integers rhs)
        requires SameType<lhs, rhs>
            && SameType<lhs, retval> {  //retval是杜撰的關(guān)鍵字,用以表示返回值
        typeof(lhs) temp(lhs);
        ...
    }
    相比之下,重載形式比較繁瑣。總體而言,盡管重載形式冗長(zhǎng)一些,但含義更加明確,更加直觀。并且在concept的接口功能作用下,對(duì)參數(shù)類型一致的要求 通常并不多見(一般在基本類型,如整型等,的運(yùn)算處理中較多見。因?yàn)檫@些操作要求類型有特定的長(zhǎng)度,以免溢出。其他類型,特別是用戶定義類型,通常由于封 裝的作用,不會(huì)對(duì)類型的內(nèi)部特性有過多要求,否則就不應(yīng)使用泛型算法)。如果可以改變語法的話,那么就能用諸如@代替typeof,==代替 SameType的方法減少代碼量:
    Integers swap(Integers lhs, Integers rhs)
        requires @lhs == @rhs && @lhs == @retval {
        @lhs temp(lhs);
        ...
    }
   

Concept、類型和對(duì)象

    事情還可以有更加夸張的發(fā)展。前面對(duì)泛型進(jìn)行了特化,能不能對(duì)類型也來一番“特化”呢?當(dāng)然可以:
    void fun(int a);
    void fun(int a:a==0); //對(duì)于類型int而言,a==0便是“特化”了
    更完整的,也可以有“局部特化”:
    void fun(int a); //#1
    void fun(int a:a==0); //#2
    void fun(int a:a>200); //#3
    void fun(int a:a<20&&a>10); //#4
    void fun(int a:(a>70&&a<90)||(a<-10)); //#5
    ...
    int a=0, b=15, c=250, d=-50;
    fun(80); //使用#5
    fun(50); //使用#1
    fun(a); //使用#2
    fun(b); //使用#4
    fun(c); //使用#3
    fun(d); //使用#5
    實(shí)際上,這無非是在參數(shù)聲明之后加上一組約束條件,用以表明該版本函數(shù)的選擇條件。沒有約束的函數(shù)版本在沒有任何約束條件匹配的情況下被選擇。對(duì)于使用立 即數(shù)或者靜態(tài)對(duì)象的調(diào)用而言,函數(shù)的選擇在編譯期執(zhí)行,編譯器根據(jù)條件直接調(diào)用匹配的版本。對(duì)于變量作為實(shí)參的調(diào)用而言,則需要展開,編譯器將自動(dòng)生成如 下代碼:
    //首先將函數(shù)重新命名,賦予唯一的名稱
    void fun_1(int a); //#1
    void fun_2(int a); //#2
    void fun_3(int a); //#3
    void fun_4(int a); //#4
    void fun_5(int a); //#5
    //然后構(gòu)造分派函數(shù)
    void fun_d(int a) {
        if(a==0)
            fun_2(a);
        else if(a>200)
            fun_3(a);
        ...
        else
            fun_1(a);
    }
    在某些情況下,可能需要對(duì)一個(gè)對(duì)象的成員做出約束,此時(shí)便可以采用這種形式:
    struct A
    {
        float x;
    };
    ...
    void fun(A a:a.x>39.7);
    ...
    這種施加在類型上的所謂“特化”實(shí)際上只是一種語法糖,只是由編譯器自動(dòng)生成了分派函數(shù)而已。這個(gè)機(jī)制在Haskell等語言中早已存在,并且在使用上帶 來很大的靈活性。如果沒有這種機(jī)制,那么一旦需要增加函數(shù)分派條件,那么必須手工修改分派函數(shù)。如果這些函數(shù),包括分派函數(shù),是第三方提供的代碼,那么修 改將是很麻煩的事。而一旦擁有了這種機(jī)制,那么只需添加一個(gè)相應(yīng)的函數(shù)重載即可。
    當(dāng)concept-類型重載和類型-對(duì)象重載混合在一起時(shí),便體現(xiàn)更大的作用:
    void fun(anytype a);
    void fun(Integers a);
    void fun(Floats a);
    void fun(long a);
    void fun(int a);
    void fun(double a);
    void fun(double a:a==0.8);
    void fun(short a:a<10);
    void fun(string a:a=="abc");
    ...
    concept-類型-對(duì)象重載體系遵循一個(gè)原則:優(yōu)先選擇匹配的函數(shù)中最特化的。這實(shí)際上是類型重載規(guī)則的擴(kuò)展。大的來說,所有類型比所屬的 concept更加特化,所有對(duì)象約束比所屬的類型更加特化。對(duì)于concept而言,如果concept A refine自concept B,那么A比B更加特化。同樣,如果一個(gè)類型的約束強(qiáng)于另一個(gè),那么前一個(gè)就比后一個(gè)更加特化,比如a==20比a>10更加特化。綜合起來,可以 有這樣一個(gè)抽象的規(guī)則:兩個(gè)約束(concept,或者施加在對(duì)象上的約束)A和B,作用在類型或者對(duì)象上分別產(chǎn)生集合,如果A產(chǎn)生的集合是B產(chǎn)生的集合 的真子集,那么便認(rèn)為A比B更加特化。
    根據(jù)這些規(guī)則,實(shí)際上可以對(duì)一個(gè)函數(shù)的重載構(gòu)造出一個(gè)“特化樹”:

    越接近樹的根部,越泛化,越接近葉子,越特化。調(diào)用時(shí)使用的實(shí)參便在這棵“特化樹”上搜索,找到最匹配的函數(shù)版本。
    concept-類型-對(duì)象體系將泛型、類型和對(duì)象統(tǒng)一在一個(gè)系統(tǒng)中,使得函數(shù)的重載(特化)具有更簡(jiǎn)單的形式和規(guī)則。并且,這個(gè)體系同樣可以很好地在類模板上使用,簡(jiǎn)化模板的定義和使用。

類模板

    C++的類模板特化形式并不惹人喜愛:
    template<typename T> A{...}; //基礎(chǔ)模板
    template<> A<int>{...}; //顯式特化(全特化)
    template<typename T> A<T*>{...}; //局部特化
    在C++09中,可以直接用concept定義模板的類型形參:
    template<Integers T> A{...};
    實(shí)質(zhì)上,這種形式本身就是一種局部特化,因而原本那種累贅局部特化形式可以廢除,代之以concept風(fēng)格的形式:
    template<Pointer T> A{...}; //Pointer表示此處采用指針特化模板
    同樣,如果推廣到全特化,形式也就進(jìn)一步簡(jiǎn)單了:
    template<int> A{...}; //這個(gè)形式有些突兀,這里只打算表達(dá)這個(gè)意思,應(yīng)該有更“和諧”的形式
    如果模板參數(shù)是對(duì)象,則使用現(xiàn)有的定義形式:
    template<int a> A{...};
    更進(jìn)一步,可以引入對(duì)象的約束:
    template<int a:a>10> A{...};
    此外,C++中在模板特化之前需要有基礎(chǔ)模板。但實(shí)際上這是多余的,D語言已經(jīng)取消了這個(gè)限制,這對(duì)于簡(jiǎn)化模板的使用有著莫大的幫助。

從本質(zhì)上講...

    從本質(zhì)上講,我們可以把所有類型看作一個(gè)集合T={ti},而concept則是施加在類型集合上的約束。通過concept這個(gè)約束,我們便可以獲得類 型集合T的一個(gè)子集C。理論上,所有concept所對(duì)應(yīng)的類型子集Cj構(gòu)成了類型集合的冪集{Cj}。在{Cj}中,有兩類類型子集是很特殊的。一組是 T本 身,即所有類型。存在一個(gè)concept不對(duì)T施加任何約束,便得到了C0=T。第二類則是另一個(gè)極端,存在一組concept,施加在T上之后所得的類 型子集僅包含一個(gè)類型:Ci={ti}。由于這組concept與類型存在一一對(duì)應(yīng)的關(guān)系,那么我們便可以用這組concept來指代類型。也就是把類型 作為特殊的concept處理。如此,concept便同類型統(tǒng)一在一個(gè)體系中。這種處理可以使我們獲得極大的好處。
    這組特殊的concept仍舊使用對(duì)應(yīng)的類型名作為稱謂,仍舊稱之為“類型”,但其本質(zhì)上還是concept。任何一個(gè)類型,一旦創(chuàng)建,也就創(chuàng)建了相應(yīng)的特殊concept。如果在模板特化中使用一個(gè)類型的時(shí)候,實(shí)際上就是在使用相對(duì)應(yīng)的那個(gè)特殊concept:
    void func(typeA a); //盡管使用了類型名typeA,但實(shí)際上這里所指的是typeA所對(duì)應(yīng)的那個(gè)特殊concept。
    在這個(gè)concept體系的作用下,函數(shù)模板的特化和重載整個(gè)地統(tǒng)一起來(concept based overload)。
    至于作用在類型上的那種“特化”,也是同樣的道理。對(duì)于一個(gè)類型T而言,它所有的對(duì)象構(gòu)成一個(gè)集合O。如果存在一組約束作用于O,那么每 一個(gè)約束對(duì)應(yīng)著O的一個(gè)子集。理論上,我們可以構(gòu)造出一組約束,使得他們同O的每一個(gè)子集一一對(duì)應(yīng)。同樣,這些子集中有兩類子集比較特殊。一類是所有對(duì)象 的集合。另一類便是只有一個(gè)對(duì)象的子集。于是,我們可以使用這組特殊對(duì)象子集所對(duì)應(yīng)的約束指代相應(yīng)的對(duì)象。也就是將對(duì)象看作特殊的約束。如此,類型和對(duì)象 也被統(tǒng)一在一個(gè)系統(tǒng)中了。
    進(jìn)而,類型在邏輯上被作為特殊concept處理,對(duì)象則被作為特殊的類型處理。于是,這三者便可以統(tǒng)一在一個(gè)體系下,一同參與特化。

總結(jié)

    盡管形式不能代表本質(zhì),但形式的變化往往會(huì)帶來很多有益的進(jìn)步。更重要的是,很多本質(zhì)上的變化總會(huì)伴隨著形式上的改變。通過將concept、類型和對(duì)象 在邏輯上整合到統(tǒng)一的體系之中,便可以促使模板、特化、函數(shù)重載等機(jī)制在形式上達(dá)成統(tǒng)一。從而能夠簡(jiǎn)化這些功能的使用。這也是當(dāng)前重視語言(工具)易用性 的潮流的一個(gè)必然訴求。這個(gè)形式上的統(tǒng)一并非語法糖之類的表面變化。而是完全依賴于concept這個(gè)新型的類型描述(泛型)系統(tǒng)的確立和發(fā)展。 concept的出現(xiàn),彌補(bǔ)了以往泛型的不足,找回了泛型系統(tǒng)缺失的環(huán)節(jié),彌補(bǔ)了泛型同類型之間的裂痕。在此作用下,便可以構(gòu)建起concept-類型- 對(duì)象的抽象體系,用統(tǒng)一的系統(tǒng)囊括這三個(gè)原本分立的概念。在這個(gè)新的三位一體的系統(tǒng)下,使得模板的特化和重載擁有了相同的形式,進(jìn)而獲得更直觀的語義,和 更好的易用性。
posted on 2008-07-26 19:44 longshanks 閱讀(1941) 評(píng)論(10)  編輯 收藏 引用

Feedback

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-26 21:25 oldrev
這樣的話程序中會(huì)不會(huì)出現(xiàn)無數(shù)只為約束函數(shù)參數(shù)而沒其他作用的 concepts,重走 C#/Java 中 interface 的老路?  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-26 22:28 clear
c++0x 的concept不需要顯式聲明的,比如那個(gè)Swapable,任何一個(gè)類型,只要有一個(gè)滿足其條件的swap成員函數(shù),就自動(dòng)成為這個(gè)concept的一個(gè)特例存在
所以不會(huì)像java里面那樣對(duì)所有的類都implement一堆的interface  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-26 22:33 Kevin Lynx
longshanks終于又發(fā)文了。學(xué)習(xí)。  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-26 22:36 空明流轉(zhuǎn)
其實(shí)語法糖很重要。。。。  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 [未登錄] 2008-07-26 23:06 foxtail
博大精深的C++ 呵呵  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-27 00:40 bneliao
gp要一桶漿糊了  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-27 06:54 longshanks
to oldrev兄:
我不太理解“只為約束函數(shù)參數(shù)而沒其他作用的 concepts”這個(gè)概念,能否給個(gè)例子。這個(gè)問題我這么想:concept以及runtime concept同oop的interface的差異我以前的blog和toplanguage討論中都談?wù)撨^。本質(zhì)上,interface是“用一個(gè)類型來表征一組類型”,邏輯上就不那么和諧。而concept則是用一個(gè)獨(dú)立的,專門用于描述一組類型的概念實(shí)現(xiàn)這個(gè)功能。interface的弊端,比如侵入的接口、造成類型耦合等等,在concept中不會(huì)存在。運(yùn)用concept,我們可以消除這部分問題。至于其他的interface問題,可能來自于需求和設(shè)計(jì),通常也無法全部通過這種技術(shù)手段消除。
當(dāng)然就像clear兄所說,concept可以auto(需要在定義concept指定auto),這也消除了不少麻煩。只是auto需要謹(jǐn)慎,只有那些含有公共語義約定的concept,比如swappable、copyable等等,以及形式(成員)非常特殊,不可能有其他語義的類型與之混淆的情況下,才可以使用,否則容易引起混亂。  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-27 10:07 oldrev
@longshanks

在大多數(shù)地方 concept 的用途和 interface 是差不多的,定義一個(gè) Copyable 的 concept 和定義一個(gè) ICopyable 是一樣的麻煩,雖然 concept 是非侵入的。
  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-27 11:10 longshanks
@oldrev
這個(gè)就沒辦法了。這些接口都是需求設(shè)計(jì)驅(qū)使的,只是不同的手段實(shí)現(xiàn)而已。這方面的問題由于沒有廣泛的應(yīng)用,還不太清楚,需要實(shí)踐檢驗(yàn)。
concept相比interface的直接好處在于兩點(diǎn):1、不需要在接口實(shí)現(xiàn)類型產(chǎn)生前定義concept,任何時(shí)候都可以,這樣可以減少設(shè)計(jì)上的壓力。這是非侵入的好處。2、concept驅(qū)動(dòng)下的模板在runtime和compiletime是相同的,也就是同一個(gè)模板可以同時(shí)用于runtime和static,而不需要另搞一套。
間接的好處是會(huì)對(duì)語言整個(gè)模型產(chǎn)生根本性的影響,從而消除語言某些方面的復(fù)雜性和缺陷。這個(gè)我打算在下一篇blog里探討。  回復(fù)  更多評(píng)論
  

# re: GP技術(shù)的展望——先有鴻鈞后有天 2008-07-28 15:18 oldrev
@longshanks
期待ing....  回復(fù)  更多評(píng)論
  


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


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久精品伊人| 性色av一区二区三区在线观看| 欧美激情五月| 久久久久在线| 国产精品久久波多野结衣| 日韩视频在线观看| 欧美大片在线看| 一区二区三欧美| 久久久久久久久久久久久久一区 | 亚洲一区欧美激情| 亚洲欧美精品在线观看| 久久精品人人| 亚洲成人资源| 中文久久精品| 久久精品72免费观看| 免费不卡视频| 欧美丝袜一区二区| 在线观看成人小视频| 中文精品视频一区二区在线观看| 亚洲直播在线一区| 另类尿喷潮videofree| 亚洲理论电影网| 欧美在线观看一区| 欧美日韩视频专区在线播放| 国产欧美精品xxxx另类| 亚洲精品资源| 裸体一区二区三区| 亚洲视频精选| 欧美激情视频一区二区三区在线播放| 国产欧美 在线欧美| 亚洲精选久久| 欧美a级一区| 欧美诱惑福利视频| 国产精品国产馆在线真实露脸 | 国产综合欧美| 亚洲神马久久| 亚洲国产老妈| 久久精品国产亚洲aⅴ| 欧美深夜福利| 日韩一区二区精品| 欧美高清视频免费观看| 欧美一区二区高清在线观看| 国产精品久久久久99| 日韩视频二区| 亚洲观看高清完整版在线观看| 性做久久久久久久久| 国产精品久久久久久久久婷婷| 美国十次成人| 国产精品高潮呻吟| 影音先锋亚洲视频| 欧美一区二区三区在线免费观看| 日韩天堂av| 欧美精品久久一区二区| 亚洲人成绝费网站色www| 久久久无码精品亚洲日韩按摩| 亚洲天堂久久| 国产精品视频福利| 亚洲欧美综合国产精品一区| 一区二区免费在线播放| 欧美色图麻豆| 亚洲欧美一区二区激情| 亚洲尤物在线视频观看| 国产精品毛片在线看| 欧美一区二区三区的| 亚洲欧美国产高清| 国产亚洲欧美一区| 久久午夜视频| 免费在线观看成人av| 亚洲精品美女在线观看| 亚洲国产视频a| 欧美日韩久久不卡| 宅男精品视频| 亚洲尤物在线| 在线观看日韩欧美| 亚洲国产欧美一区二区三区久久| 欧美.www| 亚洲综合国产激情另类一区| 亚洲自拍啪啪| 影音先锋日韩精品| 亚洲精品午夜精品| 国产欧美日韩综合精品二区| 久久先锋影音| 欧美成人精品h版在线观看| 99视频精品全部免费在线| 99伊人成综合| 国产在线拍偷自揄拍精品| 蜜桃精品一区二区三区| 欧美久久电影| 久久久视频精品| 欧美久久久久免费| 久久精品一区二区| 欧美精品自拍偷拍动漫精品| 午夜精品www| 麻豆久久精品| 欧美一级专区| 欧美成人在线免费视频| 亚洲欧美日韩高清| 狼狼综合久久久久综合网| 夜夜爽99久久国产综合精品女不卡 | 麻豆av一区二区三区久久| 在线亚洲伦理| 久久久蜜桃精品| 午夜视频一区二区| 免费视频一区| 久久精品一区蜜桃臀影院| 欧美另类极品videosbest最新版本| 欧美一级网站| 欧美视频一区二区三区…| 亚洲区欧美区| 在线欧美影院| 欧美激情在线观看| 亚洲综合久久久久| 欧美一级视频免费在线观看| 国产精品国内视频| 性欧美大战久久久久久久免费观看| 欧美激情一区在线观看| 亚洲激情在线观看| 国产久一道中文一区| 亚洲区在线播放| 亚洲高清资源| 久久九九电影| 久久久久久综合网天天| 国产精品乱码人人做人人爱| 亚洲乱码精品一二三四区日韩在线 | 欧美三级乱码| 亚洲人午夜精品| 亚洲精选视频免费看| 久色成人在线| 欧美风情在线| 亚洲激情成人网| 久久久久99精品国产片| 欧美影院在线| 国产一区二区精品| 久久狠狠久久综合桃花| 久久久亚洲精品一区二区三区| 国产日产精品一区二区三区四区的观看方式 | 亚洲欧美日韩一区在线| 欧美日韩免费观看一区三区 | 欧美精品免费观看二区| 亚洲国产cao| 亚洲伦理中文字幕| 欧美精品一区二区在线播放| 亚洲国产精品精华液网站| 亚洲第一区中文99精品| 免费看精品久久片| 亚洲国产一区视频| 亚洲视频在线视频| 国产精品第2页| 亚洲欧美日韩直播| 久久裸体艺术| 另类天堂视频在线观看| 国产女精品视频网站免费| 亚洲午夜视频在线| 欧美一级淫片aaaaaaa视频| 国产欧美一区二区精品仙草咪| 欧美一级专区免费大片| 欧美成人69| 99精品黄色片免费大全| 国产精品久久久久77777| 午夜在线电影亚洲一区| 欧美不卡视频一区发布| 在线视频免费在线观看一区二区| 国产精品免费网站| 久久久水蜜桃| 夜夜夜精品看看| 久久久久女教师免费一区| 亚洲黄色免费网站| 国产精品女主播| 另类av导航| 亚洲在线免费观看| 欧美激情黄色片| 欧美一级大片在线观看| 亚洲国产精品一区制服丝袜| 国产精品毛片| 欧美激情成人在线| 久久精品一区二区国产| 日韩一级成人av| 嫩草伊人久久精品少妇av杨幂| 亚洲视频中文字幕| 91久久嫩草影院一区二区| 国产欧美日韩麻豆91| 欧美精品一区在线播放| 久久久精品国产一区二区三区| 日韩一区二区精品葵司在线| 浪潮色综合久久天堂| 亚洲欧美日韩在线高清直播| 亚洲人成艺术| 在线播放亚洲一区| 国产午夜亚洲精品理论片色戒| 欧美日韩日本国产亚洲在线| 久久综合国产精品| 欧美在线视频观看免费网站| 中日韩美女免费视频网站在线观看| 欧美激情在线免费观看| 久久久亚洲人| 欧美在线亚洲在线| 香蕉成人久久| 亚洲欧美日韩高清| 一区二区三区国产精华| 亚洲精品久久视频|