99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

C++模板學(xué)習(xí)筆記:從編譯期代碼生成到C++20 Concepts

C++模板學(xué)習(xí)筆記:從編譯期代碼生成到C++20 Concepts C模板一直是我學(xué)習(xí)之路上繞不過去的一座山。寫這篇學(xué)習(xí)筆記之前我已經(jīng)在項(xiàng)目里被模板編譯錯誤折磨過好多次——明明照著文檔寫了編譯器就是看不懂我的代碼。后來我換了個思路去理解它模板根本不是“帶類型的函數(shù)”而是一套讓類型作為參數(shù)參與編譯的代碼生成機(jī)制。想通這一點(diǎn)之后之前那些報(bào)錯突然就變得有跡可循了。這篇文章可以看成我重新整理過的C模板學(xué)習(xí)筆記從函數(shù)模板和類模板的基礎(chǔ)語法開始一路講到特化、變參模板、模板元編程再到C20的Concept。適合兩類人讀一是剛開始接觸模板、想系統(tǒng)建立概念的初學(xué)者二是寫過一點(diǎn)模板代碼但經(jīng)常被編譯錯誤卡住、想提升排查能力的人。我會把每一部分都配合真實(shí)可運(yùn)行的代碼片段順帶分享一些我在實(shí)際開發(fā)中被坑過的地方。1. 模板到底解決了什么問題從重復(fù)代碼到類型參數(shù)化1.1 一段讓我決定認(rèn)真學(xué)模板的重復(fù)代碼兩年前我在某個內(nèi)部工具項(xiàng)目里寫過一段“三胞胎”代碼。需求很簡單求兩個值里的較大者但調(diào)用方有時(shí)傳int有時(shí)傳double有時(shí)傳std::string。我當(dāng)時(shí)的做法是完全復(fù)制粘貼改一改參數(shù)類型和函數(shù)名像這樣int max_int(int a, int b) { return a b ? a : b; } double max_double(double a, double b) { return a b ? a : b; } std::string max_string(const std::string a, const std::string b) { return a b ? a : b; }三個函數(shù)邏輯一模一樣只是類型不同。更麻煩的是后來需求變了比較規(guī)則從“大于”改成“絕對值更大”我就要同步修改三處代碼漏改一處線上行為就會出現(xiàn)詭異的不一致。那段時(shí)間我深刻體會到一個道理重復(fù)代碼的維護(hù)成本是乘積增長的而不只是求和。真正讓我下定決心啃模板的就是這一堆不斷擴(kuò)散的“三胞胎”。1.2 模板的“編譯期鴨子類型”實(shí)例化才是核心用模板改寫上面的問題代碼量立刻縮成一份template typename T T my_max(const T a, const T b) { return a b ? a : b; }關(guān)鍵在于理解上面的my_max并不是一個真正的函數(shù)它只是一份“函數(shù)藍(lán)圖”。編譯器看到my_max(1, 2)時(shí)會用int替換掉模板參數(shù)T生成一份針對int的真實(shí)函數(shù)看到my_max(1.5, 2.5)時(shí)再生成一份針對double的。這個過程叫模板實(shí)例化發(fā)生在編譯期運(yùn)行期完全不感知模板的存在。我習(xí)慣用模具來類比模板是模具本身實(shí)例化出來的函數(shù)才是被沖壓出的零件。同一個模具改變原材料類型就能做出不同材質(zhì)但形狀相同的零件。這個理解幫我解決了很多疑惑——比如為什么模板類可以接受那些只支持部分操作的類型因?yàn)槌蓡T函數(shù)是按需實(shí)例化的你沒用到某個成員函數(shù)編譯器就不會去檢查它內(nèi)部的運(yùn)算合不合法。1.3 模板代碼與普通代碼的三點(diǎn)不同在實(shí)際工程里模板代碼給人的“脾氣”和普通函數(shù)很不一樣我總結(jié)了三條最重要的差異第一運(yùn)行期開銷為零。模板實(shí)例化在編譯期完成生成的是普通函數(shù)沒有虛函數(shù)那樣的間接跳轉(zhuǎn)沒有額外的運(yùn)行時(shí)類型信息。作為對比如果用基類指針加虛函數(shù)實(shí)現(xiàn)類似效果運(yùn)行期每一次調(diào)用都要查虛函數(shù)表。第二錯誤往往出現(xiàn)在使用處而不是定義處。模板定義本身經(jīng)常是“法外之地”比如上面my_max要求類型支持operator。你把這個模板定義放在頭文件里編譯器不會立刻報(bào)錯只有在某個使用處傳入一個不支持operator的類型時(shí)編譯器才會把長長的實(shí)例化調(diào)用鏈甩到你臉上。第三定義必須可見。普通函數(shù)可以聲明在頭文件、定義在源文件鏈接器最后把它們拼起來模板不行因?yàn)閷?shí)例化需要看到完整定義。很多新手第一次寫模板習(xí)慣性地把實(shí)現(xiàn)放在.cpp里結(jié)果一鏈接變成一堆“undefined reference”這是模板學(xué)習(xí)的第一個經(jīng)典大坑。這三條差異構(gòu)成了理解后面所有內(nèi)容的基礎(chǔ)。我見過太多人糾結(jié)模板語法本身卻忽略了模板的“編譯期代碼生成”本質(zhì)導(dǎo)致遇到報(bào)錯時(shí)無從下手。2. 函數(shù)模板與類模板入門第一步的關(guān)鍵細(xì)節(jié)2.1 函數(shù)模板的參數(shù)推導(dǎo)與顯式指定函數(shù)模板最讓人舒爽的一點(diǎn)是大部分時(shí)候不需要你手動指定類型編譯器會自動推導(dǎo)模板參數(shù)auto v1 my_max(1, 2); // T推導(dǎo)為int auto v2 my_max(1.5, 2.5); // T推導(dǎo)為double auto v3 my_max(a, z); // T推導(dǎo)為char但推導(dǎo)并不是萬能的。我踩過的第一個坑是調(diào)用my_max(1, 2.5)時(shí)編譯器直接報(bào)錯“template argument deduction failed”。原因是模板參數(shù)T同時(shí)出現(xiàn)在const T a和const T b兩個位置編譯器遇到int和double兩種實(shí)參時(shí)無法確定T到底該選哪個。這時(shí)候有兩個選擇顯式指定模板參數(shù)讓int隱式轉(zhuǎn)換成double或者修改模板讓兩個參數(shù)接受不同類型。auto v my_maxdouble(1, 2.5); // 顯式指定T為double顯式指定模板參數(shù)的一個常見場景是函數(shù)參數(shù)和返回值類型有關(guān)聯(lián)但又不完全能從參數(shù)推導(dǎo)出來比如想要返回值類型和某個參數(shù)類型不同時(shí)。另一個容易忽略的規(guī)則形如const T的參數(shù)推導(dǎo)時(shí)T剝掉引用和頂層const。比如傳一個const int進(jìn)去T推導(dǎo)為int而不是const int。這個細(xì)節(jié)在涉及類型萃取和完美轉(zhuǎn)發(fā)時(shí)會變得非常重要建議一開始就有意識地去注意。2.2 類模板的靜態(tài)成員與友元函數(shù)三個容易混淆的點(diǎn)類模板的語法本身并不復(fù)雜無非是把類變成“模具”template typename T class Box { public: static int count; T value; void print() const; }; template typename T int BoxT::count 0;但有三個點(diǎn)我直到實(shí)際寫代碼時(shí)才真正理解第一個是靜態(tài)成員屬于每個實(shí)例。Boxint和Boxdouble各自擁有一份獨(dú)立的count因?yàn)樗鼈儽举|(zhì)上是兩個不同的類。你可以在Boxint里累加計(jì)數(shù)Boxdouble::count依然是0兩者互不影響。第二個是成員函數(shù)按需實(shí)例化。如果某個類型可以構(gòu)造出Box但print()內(nèi)部調(diào)用了這個類型不支持的接口只要整個程序里沒有調(diào)用過Box該類型::print()編譯就能通過。這種“懶加載”特性在泛型約束不足的時(shí)候很危險(xiǎn)——你可能以為所有類型都支持某個操作結(jié)果撐到運(yùn)行時(shí)才炸。第三個是友元聲明用法特殊。在類模板里聲明友元函數(shù)模板要么用friend void func(T);聲明依賴模板參數(shù)的友元要么用template typename U friend void func(U);聲明一個獨(dú)立的友元模板。寫錯的情況下你會得到一堆“鏈接錯誤”或者“重復(fù)聲明”的奇怪報(bào)錯。2.3 為什么模板的聲明和定義不能分開放這個問題被問過無數(shù)次也是我最早踩的坑之一。普通函數(shù)可以這樣寫// foo.h int add(int a, int b); // foo.cpp int add(int a, int b) { return a b; }編譯時(shí)使用add的源文件只要看到聲明就生成調(diào)用代碼至于定義在哪鏈接器負(fù)責(zé)去找。模板不一樣編譯器在需要實(shí)例化template typename T T my_max(...)的時(shí)候必須看到模板的完整定義才能往里填入T并生成代碼。如果頭文件里只有聲明調(diào)用處只知道“有這么個模板”卻不知道函數(shù)體是什么編譯器就只能放棄把問題留給鏈接器于是出現(xiàn)一堆完全看不懂的undefined reference。解決方案主要有兩種。最常用的是把模板實(shí)現(xiàn)也寫在頭文件里這也是標(biāo)準(zhǔn)庫一直以來的做法另一種是在源文件里顯式實(shí)例化比如// template_impl.cpp template int my_maxint(const int, const int); template double my_maxdouble(const double, const double);這相當(dāng)于提前把指定類型的實(shí)例生成好鏈接器就能找到定義。但顯式實(shí)例化的缺點(diǎn)也很明顯每個需要用到的類型都得手寫一遍一旦類型多起來維護(hù)成本比重復(fù)代碼還可怕。所以絕大部分項(xiàng)目都會選擇第一種“頭文件內(nèi)定義”的方式。3. 模板特化與偏特化編譯器在分支路口如何做選擇3.1 全特化的寫法與適用場景模板實(shí)例化時(shí)編譯器默認(rèn)是用一個統(tǒng)一“模具”生成代碼。但某些類型可能有更好的實(shí)現(xiàn)方式這時(shí)就可以為特定類型開小灶這就是全特化。比如前面那個my_max遇到const char*這種C風(fēng)格字符串如果用默認(rèn)的operator去比較比的是指針地址而不是字符串內(nèi)容結(jié)果完全不符合直覺。這時(shí)候可以寫一個全特化版本template const char* my_maxconst char*(const char* const a, const char* const b) { return std::strcmp(a, b) 0 ? a : b; }全特化的關(guān)鍵字是template 后面跟一個完全確定類型的函數(shù)或類定義。編譯器在為const char*做實(shí)例化時(shí)會優(yōu)先找到這個特化版本而不是通用模板。我當(dāng)時(shí)的理解是通用模板是默認(rèn)工廠流程全特化是給特定訂單單獨(dú)開了一條生產(chǎn)線。不過這里必須提醒一句函數(shù)模板的全特化其實(shí)很容易被忽略尤其在存在函數(shù)重載的時(shí)候。編譯器選擇順序是先看非模板函數(shù)再看模板特化最后才看模板實(shí)例化。如果項(xiàng)目中同時(shí)存在一個同名同參的非模板函數(shù)和一個全特化版本非模板函數(shù)往往被優(yōu)先選中這個行為常常讓人困惑。所以我在實(shí)踐中更傾向于用函數(shù)重載而不是函數(shù)模板全特化但類模板沒有重載這回事只能特化。3.2 類模板偏特化指針、引用與const的幾種典型偏特化類模板只有全特化和偏特化沒有“重載”。偏特化是指保留部分模板參數(shù)只對某一種模式做專門處理。最常見的應(yīng)用場景是針對指針類型、引用類型、const類型做差異處理。template typename T class Wrapper { public: T data; }; // 針對指針類型的偏特化 template typename T class WrapperT* { public: T* ptr; }; // 針對const類型的偏特化 template typename T class Wrapperconst T { public: T value; // 注意這里T本身剝掉了const };偏特化的本質(zhì)是“模式匹配”。WrapperT*匹配任何指針類型Wrapperconst T匹配任何const類型。編譯器會按匹配程度選一個最合適版本比如Wrapperconst int*既可以被WrapperT*匹配Tconst int也可以被Wrapperconst T匹配Tint*但最終選擇時(shí)部分特化與參數(shù)模式的貼合程度會被比較通常T*更貼合因?yàn)橥饷嬉粚邮侵羔樓覂?nèi)部是const int。這里有個細(xì)節(jié)我原來常弄混偏特化只能用于類模板不能用于函數(shù)模板。函數(shù)模板想要類似效果應(yīng)該用重載。所以如果有人試圖給函數(shù)模板寫template typename T void funcT*(T*)這樣的偏特化語法編譯器會直接拒絕。3.3 特化與重載的優(yōu)先級一個讓我調(diào)試到崩潰的例子有一次我在項(xiàng)目里給一個工具庫寫了這樣的代碼template typename T void handle(const T value) { std::cout generic std::endl; } template void handleint(const int value) { std::cout int specialization std::endl; } void handle(const int value) { std::cout non-template overload std::endl; }調(diào)用handle(42)時(shí)我滿心以為輸出的是int specialization結(jié)果控制臺打印出來的是non-template overload。查了好半天才發(fā)現(xiàn)編譯器在選擇重載時(shí)非模板版本優(yōu)先于模板特化版本。這條規(guī)則我后來在標(biāo)準(zhǔn)條款里確認(rèn)過如果非模板函數(shù)和模板特化都能匹配非模板函數(shù)優(yōu)先。這件事給我的教訓(xùn)是不要試圖用函數(shù)模板特化去“覆蓋”重載決議它的行為既不直觀又容易讓維護(hù)者誤會。函數(shù)模板想針對特定類型做區(qū)分正確姿勢是寫一個更特化的函數(shù)重載或者用后面會講到的if constexpr/概念約束。類模板特化才是干凈利落的解決方案。4. 變參模板與折疊表達(dá)式簡化重復(fù)代碼的實(shí)用工具4.1 參數(shù)包展開的三種方式變參模板variadic templates是我學(xué)會之后覺得“真香”的特性。它允許模板接受任意數(shù)量、任意類型的參數(shù)。C11引入時(shí)主要是為了配合完美轉(zhuǎn)發(fā)實(shí)現(xiàn)工廠函數(shù)后來C17折疊表達(dá)式讓這個語法又好寫了非常多。先看最經(jīng)典的遞歸展開方式。要打印任意個參數(shù)可以這樣void print_all() { // 遞歸終止函數(shù)空參數(shù)包時(shí)結(jié)束 } template typename T, typename... Args void print_all(const T first, const Args... rest) { std::cout first ; print_all(rest...); // 每次剝掉一個參數(shù) }typename... Args聲明一個參數(shù)包Args... rest在函數(shù)參數(shù)列表中表示一組參數(shù)。遞歸展開每次取出第一個參數(shù)剩下的繼續(xù)遞歸直到參數(shù)包為空時(shí)調(diào)用無參重載。這是最直觀的展開方式邏輯清晰但每層遞歸都要生成一個新模板實(shí)例編譯代價(jià)略高。第二種方式是用初始化列表配合逗號表達(dá)式一次性展開template typename... Args void print_all_init(const Args... args) { (void)std::initializer_listint{ (std::cout args , 0)... }; }這里的(std::cout args , 0)是個逗號表達(dá)式先執(zhí)行打印再生成一個int類型的0整個表達(dá)式結(jié)果就是0于是可以放進(jìn)std::initializer_listint。...把參數(shù)包展開成一組用逗號分隔的表達(dá)式。這個寫法不需要遞歸模板實(shí)例化層級少編譯效率更好缺點(diǎn)是讀起來比較勸退。第三種方式是在C17里最簡單直接的——折疊表達(dá)式下面單獨(dú)說。4.2 折疊表達(dá)式C17之后的簡潔寫法折疊表達(dá)式讓變參模板的可讀性提升了一大截。它的語法看一眼就明白一半template typename... Args void print_all_fold(const Args... args) { (std::cout ... args) std::endl; }這個表達(dá)式(std::cout ... args)是左折疊等價(jià)于把a(bǔ)rgs從左到右依次拼到std::cout上。對于打印這種沒有累積結(jié)果的場景更常用的是逗號折疊template typename... Args void print_all_fold2(const Args... args) { ((std::cout args ), ...); std::cout std::endl; }逗號折疊會把每個參數(shù)依次打印出來中間的逗號不是打印內(nèi)容而是折疊操作符。我當(dāng)時(shí)第一次看到(...)這個寫法有點(diǎn)懵但只要記住一點(diǎn)折疊表達(dá)式是對參數(shù)包做一次編譯期的二元?dú)w約一元右折(args op ...)從最后一個參數(shù)開始一元左折(... op args)從第一個參數(shù)開始。折疊表達(dá)式特別適合做求和、拼接、邏輯與這類累積操作。比如template typename... Args auto sum_all(Args... args) { return (args ... 0); // 二元折疊初始值0避免空包報(bào)錯 }注意空參數(shù)包時(shí)沒有初始值的折疊表達(dá)式是非法的所以求和時(shí)最好加上一個初始值。4.3 變參模板在工廠函數(shù)與完美轉(zhuǎn)發(fā)中的應(yīng)用變參模板最常見的一個實(shí)際場景是寫工廠函數(shù)。標(biāo)準(zhǔn)庫里的std::make_shared、std::make_unique本質(zhì)就是變參模板加完美轉(zhuǎn)發(fā)。一個簡化版本可以這樣寫template typename T, typename... Args std::shared_ptrT my_make_shared(Args... args) { return std::shared_ptrT(new T(std::forwardArgs(args)...)); }這里的關(guān)鍵是Args... args和std::forwardArgs(args)...。Args不是普通的右值引用而是轉(zhuǎn)發(fā)引用也叫萬能引用它可以根據(jù)實(shí)參自動推導(dǎo)成左值引用或右值引用。std::forward的作用是保留參數(shù)原有的值類別如果調(diào)用方傳進(jìn)來的是一個左值就按左值轉(zhuǎn)發(fā)如果是右值就按右值轉(zhuǎn)發(fā)。這樣一來構(gòu)造函數(shù)里不會因?yàn)閰?shù)中途丟失“移動語義”或“拷貝語義”而引發(fā)不必要的拷貝。我第一次接觸這個寫法時(shí)總是想不通為什么要這么繞。后來我明白了在模板函數(shù)內(nèi)部具名的參數(shù)都是左值哪怕實(shí)參原本是右值。如果不加std::forward原本可以移動構(gòu)造的對象被迫拷貝構(gòu)造性能白白損失。這個細(xì)節(jié)在寫高性能容器、事件分發(fā)系統(tǒng)時(shí)非常關(guān)鍵。5. 模板元編程與類型萃取把運(yùn)行期的判斷搬到編譯期5.1std::is_same和std::enable_if的搭配模板真正強(qiáng)大的地方不只在于生成代碼還在于可以在編譯期“根據(jù)類型做判斷”。C11標(biāo)準(zhǔn)庫提供了大量類型萃取工具比如std::is_sameT, U專門用來判斷兩個類型是否一致。但如果你直接這么寫多半會掉坑里template typename T void process(const T value) { if (std::is_sameT, int::value) { // 假設(shè)這里調(diào)用了value.someIntMethod() } else { // 假設(shè)這里調(diào)用了value.someStringMethod() } }問題在于模板實(shí)例化時(shí)if的兩個分支都會被編譯無論T是int還是std::string兩個分支里那些“不存在的方法”都會導(dǎo)致編譯失敗。運(yùn)行期判斷無法阻止編譯期錯誤。正確做法是讓不滿足條件的分支從編譯過程里直接消失。std::enable_if就是為此設(shè)計(jì)的template typename T typename std::enable_ifstd::is_sameT, int::value, void::type process(const T value) { std::cout 處理int std::endl; } template typename T typename std::enable_if!std::is_sameT, int::value, void::type process(const T value) { std::cout 處理其他類型 std::endl; }std::enable_if條件, 類型::type只在條件為真時(shí)才存在條件為假時(shí)整個函數(shù)聲明就是非法的編譯器直接丟棄這個重載。這相當(dāng)于在編譯期做了一次“替換失敗不是錯誤”SFINAE的篩選。不過說實(shí)話這種寫法讀起來很拗口。C17之后有了if constexpr相同場景簡單得多template typename T void process(const T value) { if constexpr (std::is_sameT, int::value) { // 只在T是int時(shí)編譯 } else { // 只在T不是int時(shí)編譯 } }if constexpr的真正意思是“在編譯期選擇一個分支另一個分支不實(shí)例化”。這比enable_if直觀太多所以我的經(jīng)驗(yàn)是新項(xiàng)目盡量用if constexprenable_if更多用于需要參與重載決議的場合。5.2 一個編譯期階乘模板理解遞歸實(shí)例化的邊界模板元編程最經(jīng)典的教學(xué)示例是在編譯期計(jì)算階乘。用模板遞歸來實(shí)現(xiàn)template int N struct Factorial { static const int value N * FactorialN - 1::value; }; // 偏特化/特化提供遞歸終止條件 template struct Factorial0 { static const int value 1; }; // 用法 static_assert(Factorial5::value 120, 5! should be 120);這段代碼展示了一個元編程的核心模式用模板參數(shù)驅(qū)動遞歸用特化提供終止條件。Factorial5實(shí)例化時(shí)需要Factorial4Factorial4又需要Factorial3……直到Factorial0這個特化版本提供了出口。我在學(xué)習(xí)時(shí)問過自己既然C11就有constexpr函數(shù)了為什么還要研究模板遞歸因?yàn)閮烧邆?cè)重點(diǎn)不同。constexpr函數(shù)是可以被編譯期計(jì)算的普通函數(shù)寫法更自然適用范圍更廣但模板遞歸可以在“編譯期產(chǎn)生類型”比如根據(jù)整數(shù)常量生成不同的類型結(jié)構(gòu)這是constexpr函數(shù)做不到的。現(xiàn)代C實(shí)踐中復(fù)雜元編程確實(shí)越來越少用“階乘”這種把戲但理解遞歸實(shí)例化對弄明白模板是怎么一層層展開出錯誤信息非常有幫助。5.3 元編程的局限編譯時(shí)間、可讀性與維護(hù)成本我見過有些開發(fā)者學(xué)會模板元編程后恨不得把所有邏輯塞進(jìn)編譯期結(jié)果項(xiàng)目編譯時(shí)間從十幾秒暴漲到幾分鐘。元編程是有代價(jià)的每一層模板實(shí)例化編譯器都要做一次“類型替換 模式匹配 代碼生成”復(fù)雜元程序甚至?xí)?shí)例化成千上萬個模板錯誤信息動輒幾百行。更麻煩的是可維護(hù)性。元編程代碼常常“反人類”沒有正常的循環(huán)和變量只有遞歸和常量調(diào)試器里幾乎看不到運(yùn)行時(shí)的中間值加了static_assert可能還好一旦缺少診斷信息后人維護(hù)時(shí)只能靠猜。我的經(jīng)驗(yàn)法則很簡單能用constexpr函數(shù)算出來的就別用模板元編程能用運(yùn)行期算的也別硬搬進(jìn)編譯期。模板元編程最適合處理的是“類型的選擇與轉(zhuǎn)換”比如判斷某類型是否滿足某接口、在不同類型之間做編譯期分發(fā)。至于業(yè)務(wù)計(jì)算交給constexpr函數(shù)和普通函數(shù)就好別為了炫技把整個項(xiàng)目拖入編譯地獄。6. C20 Concepts讓模板報(bào)錯從“天書”變成人話6.1 定義一個自己的概念直到C20之前模板的約束只能靠enable_if這種“負(fù)向篩選”。問題是當(dāng)約束不滿足時(shí)編譯器給出的錯誤信息往往是一大串“模板參數(shù)推導(dǎo)失敗候選模板被忽略”完全沒有告訴你“為什么失敗”。Concepts概念就是為了解決這個問題。概念定義看起來像對類型的一組“體檢要求”。舉個例子我想定義一個“可相加的”概念#include concepts template typename T concept Addable requires(T a, T b) { { a b } - std::convertible_toT; };這里requires后面跟的花括號是個requires表達(dá)式里面可以寫三類要求簡單要求表達(dá)式合法、類型要求typename后面跟的類型存在、復(fù)合要求{表達(dá)式} - 約束既要求表達(dá)式合法又要求結(jié)果滿足某個約束。上面的概念表示T類型要滿足任意兩個T對象相加的結(jié)果必須能轉(zhuǎn)換成T。如果某個類型不支持operator或者加出來的結(jié)果不是T概念檢查就失敗。6.2 把概念用進(jìn)函數(shù)模板的三種寫法定義好概念后約束函數(shù)模板有多種等效寫法我三種都在項(xiàng)目里見過// 寫法一requires子句 template typename T requires AddableT T add(T a, T b) { return a b; } // 寫法二約束模板參數(shù) template Addable T T add(T a, T b) { return a b; } // 寫法三約束auto參數(shù) Addable auto add(Addable auto a, Addable auto b) { return a b; }這三種寫法表達(dá)的是同一個意思選哪種更多是風(fēng)格問題。我個人的偏好是第二種template Addable T它把約束直接寫進(jìn)模板參數(shù)列表讀起來最自然。第一種適合約束條件比較復(fù)雜、需要多行requires表達(dá)式的情況。第三種雖然簡潔但適合用在約束很輕的場景如果概念本身很復(fù)雜會讓函數(shù)聲明顯得擁擠。概念帶來的最大好處是錯誤信息質(zhì)量顯著提升。當(dāng)你用一個不支持的類型去調(diào)用add時(shí)編譯器會直接告訴你“約束未滿足因?yàn)镾omeType不滿足Addable”。雖然還是有一定閱讀門檻但相比之前滿屏的模板參數(shù)替換記錄已經(jīng)像人話了。6.3 概念對重載決議的影響與注意點(diǎn)概念不只是語法糖它還參與重載決議。簡單說更受約束的函數(shù)模板在重載時(shí)會勝出。比如template typename T requires std::integralT void test(T) { std::cout 整型版本 std::endl; } template typename T requires std::signed_integralT void test(T) { std::cout 有符號整型版本 std::endl; }如果調(diào)用test(3)兩個模板都能匹配但std::signed_integral比std::integral更嚴(yán)格多了“有符號”的限制編譯器認(rèn)為它的約束更“受約束”所以第二個版本勝出。這個機(jī)制叫約束偏序編譯器會自動比較兩個約束的邏輯包含關(guān)系。這里要特別注意一點(diǎn)約束偏序的判斷依賴于約束表達(dá)式本身的結(jié)構(gòu)不一定總能推導(dǎo)出“更嚴(yán)格”。如果兩個概念之間沒有明顯的蘊(yùn)含關(guān)系調(diào)用時(shí)就會報(bào)重載歧義。我在寫具有多個約束版本的重載時(shí)會刻意給概念起名并保持概念的邏輯層級清晰比如Integral和SignedIntegral這種直接體現(xiàn)包含關(guān)系的命名重載決議和行為都更容易預(yù)測。7. 我踩過的模板編譯錯誤與排查思路7.1 從“no matching function”到真正的調(diào)用棧模板編譯報(bào)錯最常見的開頭就是error: no matching function for call to ...緊跟著一屏幕候選模板。剛開始我每次都從第一行開始讀結(jié)果一頭扎進(jìn)幾百行的“模板實(shí)例化調(diào)用鏈”里出不來。后來我總結(jié)出一個更高效的排查順序先看調(diào)用點(diǎn)的實(shí)參類型是否和函數(shù)模板參數(shù)匹配。比如傳了一個std::string但函數(shù)參數(shù)是const T這通常沒問題但如果實(shí)參是int*模板參數(shù)又是T推導(dǎo)結(jié)果就是int*后續(xù)函數(shù)體里若把它當(dāng)成整數(shù)用就會報(bào)錯。所以先確認(rèn)推導(dǎo)出來的T是什么再往函數(shù)體里看。其次檢查返回值類型相關(guān)表達(dá)式。很多“no matching function”并不是調(diào)用參數(shù)不匹配而是返回值類型所在的enable_if條件不滿足整個候選模板被SFINAE規(guī)則丟棄。最后才去看輸出列表末尾那幾行“實(shí)例化自”位置那里通常指向你業(yè)務(wù)源碼中真正出錯的那一行。編譯器的調(diào)用鏈?zhǔn)菑哪0宥x開始展開的最底部的層次往往才是你的業(yè)務(wù)調(diào)用點(diǎn)從下往上讀會更高效。7.2 模板定義必須可見鏈接期錯誤的定位還有一類錯誤不在編譯期爆發(fā)而是藏在鏈接期。典型報(bào)錯是undefined reference to void my_maxint(const int, const int)這個報(bào)錯信息里甚至有模板參數(shù)int但很多人第一眼看不出它和模板有什么關(guān)系。原因就是前面說過的模板的定義放在了.cpp里調(diào)用方頭文件里只有聲明實(shí)例化被迫中斷最后鏈接器發(fā)現(xiàn)找不到對應(yīng)符號。遇到這種報(bào)錯排查路徑是先去檢查該模板定義所在文件是否被包含在調(diào)用方的編譯單元里再確認(rèn)是否有人在.cpp里做了顯式實(shí)例化但拼錯了類型。另一個容易忽略的情況是類模板的靜態(tài)成員定義忘了寫這也會在鏈接期出現(xiàn)類似“undefined reference toBoxint::count”的報(bào)錯解決方式是回到類外補(bǔ)上模板靜態(tài)成員的定義。7.3 用靜態(tài)斷言和“類型打印”工具輔助診斷排查模板類型推導(dǎo)問題時(shí)我特別依賴一個“手工類型打印”的技巧。核心思路是寫一個故意不定義的模板類讓編譯器在報(bào)錯時(shí)把類型“帶”出來template typename... struct TypePrinter; // 故意不定義 template typename T void debug_type(T) { // 觸發(fā)編譯錯誤報(bào)錯信息中會顯示T的類型 static_assert(sizeof(TypePrinterT) 0, 查看T的類型); }只要某個地方調(diào)用了debug_type(expr)編譯器就會在static_assert那里報(bào)錯錯誤信息里會顯示TypePrinterint或者TypePrinterconst char ()[6]這類類型全名。這種手段在排查引用、const、數(shù)組退化的推導(dǎo)問題時(shí)比任何調(diào)試器都好用。另一個常用工具是static_assert搭配類型萃取static_assert(std::is_samedecltype(x), int::value, 這里推導(dǎo)出來的類型不是int);一旦條件不滿足編譯器會把你寫的提示信息打印出來。我現(xiàn)在的習(xí)慣是在寫復(fù)雜的模板函數(shù)時(shí)先在關(guān)鍵推導(dǎo)點(diǎn)放幾個臨時(shí)的static_assert確定類型無誤后再刪掉。這比依賴IDE的類型懸停提示更可靠因?yàn)榫幾g器的推導(dǎo)結(jié)果才算是最終事實(shí)。最后再分享一點(diǎn)我的個人體會。模板學(xué)習(xí)切忌只看語法一定要親手編譯看報(bào)錯修報(bào)錯。我建議初學(xué)者不要急著上模板元編程先把函數(shù)模板、類模板、特化、變參模板這四塊跑熟再試Concept。模板報(bào)錯確實(shí)難看但看得多了你會發(fā)現(xiàn)它其實(shí)有規(guī)律可循編譯器會把整個實(shí)例化調(diào)用鏈展開你只要從最底層的一條開始看。后續(xù)我還會繼續(xù)整理模板相關(guān)的學(xué)習(xí)筆記比如模板參數(shù)推導(dǎo)的完整規(guī)則和約束偏序的細(xì)節(jié)那又是兩個大坑。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
婷婷大香焦| 激情亚洲五月| 天天日夜夜草进麻麻的子宫| 日韩在线观看网址| 香蕉婷婷| 久久激情五月婷婷| 思思热99在线| 亚洲国产精品五月天| 成人av在线网| 色播五月天激情| 日撸夜撸日操| 日日爽日日操| 九九久久99| 五月丁香六月婷综合成人综合| 亚洲操逼网| 大战熟女丰满人妻AV| 色五月综合激情| 一级精品999WWW| 免费看欧美成人A片无码| 最新丁香六月婷婷| 国产精品视频久久99| 五月天婷婷影院| 久久久国产精品黄毛片| 天天日天天干天天操| 久久这里只有国产视频| 五月丁香成人| 开心深爱五月天| 超碰免费电影| 黄色AAAAAAA| www.色婷婷| 99热成人精品网站| 日本狠狠网| 伊人成人宗合网| 久久久久8888| 欧美色99| 综合色99| 伊人91| 日韩啪啪自拍| 久久五月天精品视频| 五月天开心网| 天天干天天插| 被强行糟蹋的女人A片| 碰碰女| 思思 热 99| 婷婷色天香| av大香蕉| 综激情网| 成人片在线播放| 婷婷性爱视频在线| WWW.99视频| 日日操夜夜操中国无码| 丁香色情五月综合激情| 欧美激情伊人| 91综合色| 大香蕉520| 婷婷五月丁香欧洲| 色五月天激情| 婷婷五日b| 少妇高潮一区二区三区99欧美| 大香蕉综合视频在线| 丁香五月激情啪啪| 丁香五月欧美婷婷综合| 久久青草国| 亚洲黄色操逼| 色噜久| 玖色色综合| 丁J香六月首页| 成人五月丁香花| 国产精品久久久久久久久久久久| 亚洲中文AV| 天天躁日日躁狠狠躁日日躁2022年5月9日 | 婷婷玖玖丁香| 丁香六月婷婷综合| 五月色导航| 天天激情视频| 天堂草在线看www| 五月丁香六月婷婷国产视频| 五月丁香色色网| 丁香五月天啪啪| 激情五月丁香五月| 丁香六月丁香婷婷激情| 日亚二欧美| 99操无码视频观看| 天天射射夜| 中文字幕 久久9999| 色狠狠色综合| 99热这里有精力| 在线不卡视频| 中文不卡av| 人妻操日日| 日本在线视频播放91| 九九99精品视频| 色情五月天视频网| 婷婷射婷婷舔| 99爱在线视频| 超碰高清在线| 很操日本7| 深爱激情婷| 五月天停婷基地| 91精品丝袜久久久久久| 婷婷伊人综合| 色色色在线免费视频| 天天日天天操天天干| 欧美成人性爱网| 色欲天天综合网| 九九色热| 色五月天堂| 狠狠搞综合色| 久久久久9| 夜精品无码A片一区二区蜜桃| 99热黄| 99爱99操| 思思热久热| 91男同| 97热91| 欧洲一区二区| 天天插AV丝袜中| 久久99久久久久久| 在线超碰91| 五月婷高清视频| 婷婷激情五月天激情| 色色色热热热| 超碰在线看| 婷婷之六月丁香| 婷婷五月天综合久久| 无码少妇高潮喷水A片免费| 伊人大香蕉在线视频| 天天爽—爽| 国产婷婷五月在线视频| 婷色天堂| 三级成人网站| 大学生高潮无套内谢视频| 第五婷婷伊人丁香| 五月激情天天干| 五月天综合在线| 久久婷婷资源| 很很干夜夜干| 伊人狠狠操| 久色激情| 伊人色五月| 激情影院免费视频婷婷五月天| 另类图片激情五月| 91无码高清| 久久小说网| 中文字幕,综合,91| 99热在线观看亚洲区| 超碰97免费在线| 亚洲狠狠色丁香婷婷综合久久| 亚洲超碰在线| 思思热在线播放| 激情五月婷婷啪啪| 色色五月婷婷久久| 九九九九综合| 99这里有精品视频| 97色婷婷| 精品人妻伦一二三区久久| 五月婷婷偷拍| 超碰九色| 亚洲精品乱码久久久久久按摩观| 思思久久99| 五月丁香激情婷婷| 九九这里都是精品| 99热20| 99久视频| 99色热综合| 欧美性生交XXXXX无码小说| 婷婷,五月天,丁香,第一| 中文字幕在线日亚州9| 一本久道综合99| 久久五月天网| 色丁香五月天射婷婷爱婷婷| 亚洲天堂99| 色色五月天婷婷| 1024国产| 综合大香蕉| 日本九九网| 停停综合色色| 伊人91| 成人五月天在线视频在线观看| 91一起操| 久婷婷视平| 色播五月婷婷综合| 欧美五月婷婷综合| 色玖玖综合网| 激情伊人五月婷婷久久| 色婷婷啪啪| 五月婷丁香| 色爽九九| 国产在线aaa片一区二区99| 99热这里只有在线播放| 97超碰色| www.婷婷六月天| 99无码免费视频| 亚洲愉拍99热成人精品| 亚洲激情免费视频| 97影院一级片| www,婷婷,com| 欧美 日韩 成人 在线| 日韩不卡DvD| 激情图片五月天| 天干干夜夜操| 色爽九九| 91av视频| 五月丁香综合网| 激情五月丁香色婷婷| 久久久久久久久久久久久久久久一道本| 五月天精品综合| 91打屁股视频网站| 天天插操| 婷婷社区五月天| 久久99久久99精品免视看婷婷| 色吊丝av中文字幕| 亚洲国产精品SUV| 亚洲精品无码A片一区二区| 五月草影视| 香蕉大综综综合久久| AA丁香综合激情| 亚洲综合网激情小说| 97ai婷婷| 东京热五月婷婷| 色婷婷精品视频| 亚州激情在线视频| 五月天婷婷影院| 丁香情色五月| 人妻少妇色综合| 天天色天天爱天天爱天天爱y| 久操人妻| 色欲久久久久久综合网综合网| 五月丁香综合啪啪| 激情性爱五月天| 激情婷婷五月天日本系列| 色爱综合网| 日本www免费九九| www.五月丁香| 久久 婷婷 五月天| 丁香婷婷色五月激情综合| 人人亚洲| 日本高清久久| 亚洲另类婷婷综合| 九九人人自拍| 婷婷国产欧美97| 婷婷色色综合| 亚洲天堂婷婷丁香| 欧美叉叉叉BBB网站| 超碰在线观看99| 欧美色性色好| 五月婷婷六月色| 久久机只有这里精品| 九色视频91疯狂| 激情文学 综合 九月| 风流少妇A片一区二区蜜桃| 丁香五月综合激情啪啪| 亚洲美女网Va| 91青娱乐青青草| 亚亚州久久高潮| 五月丁香婷婷啪啪| 日本操碰碰| 99热精品中文字幕| 99热这里只有精| 激情五月视频在线婷婷| 丁香六月五月天| 严洲天天插| 激情综合4月| 九九99免费视频| 99色日本| 欧美三级欧美一级| www.婷婷| 天天色天天干天天插| 激情无码五月天| 婷婷五月天AV| 99成人网站| 都市激情久久| 成人欧美Va| 丰满人妻一区三区三区| 午夜九九电影| 日韩操逼小电影| 久热这里精品免费| 夜丁香五月婷婷| 激情开心五月亚洲| 婷婷成人五月天成人文学| 亚洲天堂aaa| 色婷婷小说| 深爱激情网综合| 99色视频免费在线规看| 538在线精品| 五月天久久丁香| 五月中旬婷婷丁香六| 九六五月天婷婷| 久热这里只有精品视频6| 91大屁股| 五月天激情小说网| 五月丁香啪啪啪| 婷综合| 亚洲AV网址| 久久曰曰| 日 日干 日日做| 色五月婷激情| 涩涩五月天| 色五月婷婷av| 伊人在线视频| 久久A极片| 99热99日天天干| 中文字幕性爱视频| 婷激情五月天视频导航| 久久久久久久久人妻| 色色a| 色欲一区二区三区精品A片| 激情四射五月天| 超碰只有精品在线| 91成人视频| 五月天婷婷自拍图片在线观看| 欧美性色五月天| 天天狠狠夜夜狠狠2023| 99热这里是精品| 日本大人久久| 久久婷婷六月| 五月天精品综合| 狠狠色 综合色区| 99综合| 久久激情五月| 欧美综合123区| 色的色综合| 激情五月天婷婷丁香 | 丁香六月欧美| 碰碰女| 五月天成人伊人| 99色在线视频| 《亚洲操B久久免费在线观看,亚洲操B久久在线播放》在线播放 - 高清资源 - 97 | 江苏少妇性BBB搡BBB爽爽爽| 色一情一乱一乱一区91| 激情五月天色婷婷| 色五月婷婷五月天| 丁香五月婷婷大香蕉| 开心丁五月| 五月丁香婷婷爱| 国产SUV精品一区二区6| 久久激情五月| 婷婷激情六月视频| 亚洲视频在线网| 五月丁香六月在线欧美| 色色五月天丁香婷婷| 激情六月天| 91久久久久久久久久| 日韩按摩二区| 嫩草AV久久伊人妇女超级A| 免费AV在线| 天天xxxxxx天天日| 免费无码毛片一区二区A片| 伊人色综合影院视频| 丁香五月网| 99久久综合| 九月久久婷婷| 99这里| 就爱日五月天| 6080av| 伊人久久婷婷| anquye伊人| 婷婷五月激情网| 色婷成人狠干| www五月天com| 丁香五月www| 婷婷香五月综合激情| 天天插天天插| 五月伊人综合| 这里有精品99| 99色免费观看全部| 亚洲色啪| 成人婷99最新| 丁香无月在线观看| 玖玖在线视频| 五月丁香亚洲综合网| 日本一级黄色电影| 色播五月丁香婷婷| 久久人人添人人爽添人人片αV| 99激情视频热| 色婷婷性爱网| 国产五月天欧美色| 久久精品99久久久久久久久| 欧美日比视频| 久久久婷| www.婷婷| 婷五月天天| 九九热在线观看视频| 玖玖色综合网| 欧美肉大捧一进一出免费视频| 噜噜色五月| 99久久99久久综合| 婷婷丁香激情| 99精品一二三四视频| 综合久久9| 日韩综合久久| 九九热只有这里精品| 久久欧洲综合网| 久久R激情| 五月婷婷我| 国产女人十八水真多1| 婷婷六月啪啪| 另类天堂| 日韩在线看AV| 人妻视频在线| 五月婷婷狠天天色综合| 69久热| 人人爱人人草| 色婷婷综合视频| www.夜夜操.com| 三级成人网站| 色久影院| 色狠狠婷婷| 五月丁香婷婷基地| 狠狠草天天草| 美欧成人视频| 夜精品无码A片一区二区蜜桃| 婷婷丁香五月亚洲综合网在线视频观看| 婷婷五月深深爱| 热婷婷av| www.婷婷六月天| m色激情网| 中文字幕97超级碰| 九月婷婷在线视频| 激情五月婷婷丁香| 丁香色五月天| 五月天婷婷色播| 9 9 9色色| www.狠狠| 婷婷五月天成人小说| 色婷婷丁香| 色哟呦av| 五月丁香六月激情欧美综合| 日本颜色视频人人爱| 人人操97| 六月丁香啪| 九九在线精点品| 久久激情五月天| wWwCom夜操wwW| 91干在线视频| 色婷婷五月综合激情中文字幕| 狼人婷婷久久| 五月天狠狠| 日操| 九九操操| 琪琪色热色色| 日本天堂网站99| 丁香五月久久| 欧美色五月| 色色色热| 亚洲激情综合免费| 天天操,天天插| 亚洲AV成人精品日韩在线播放| 五月天色软件| 超级碰碰97在线| 久久a热| 婷婷另类小说| 天天插插天天| 午夜婷婷五月天| 天天在线久久综合 | 中文字幕丰满孑伦无码专区| 亚洲第一综合| 狠狠草在线观看| 五月天婷婷在线视频| 呦呦视频无码播放| 日在线V视频在线播放| 亚洲激情网| 97欧美在线| 九久热| 欧洲综合一区| 精品九九久久| 欲求不满的人妻| 字幕网AV中文字幕| 国产精产国品一二三在观看 | 免费观看欧美成人AA片爱我多深| 九九人人操| 丁香综合网| 综合AV在线| 四虎成人精品永久免费AV九九| 五月天婷婷小说| 《蜘蛛女》梁铮1995| 五月婷婷丁香狠狠撸久久| 色综合久久88色综合天天99| 婷婷丁香激情综合色情| 五月停亭六月,六月停亭的英语| 最新久久网址| 97人人射| 婷婷天天插天天爱| 激情校园 亚洲| 日本99热| www.久久五月天.com| 99rewww| 婷婷五月天成人在线视频| 国产99久久久| 欧美婷婷五月激情| 久久久精品人妻录| 色狠狠图片| 精品久久久久久久人妻| 无套内射极品大美女| 五月婷婷在线观看黄| 99er精品视频| 国产精品日日躁夜夜躁| 五月色网| 5月丁香综合图区| 31色区视频免费看| 色琪琪一综合久久激情五月视频| 婷婷五月四狠狠| 啄木鸟黑丝一区二区| 深爱激情网噜噜色| 婷婷综合五月天| 九色91国产| 欧美性猛交99久久久99| 777久久综合视频| 色五月婷婷婷婷| 夜夜骑夜夜操| 色播五月天激情| 国产FREESEXVIDEOS性中国| 九色综合网| 久久人五月| 婷婷五月天AV| 久久精品国产色| 99热精品6| 91丨九色丨熟女| 色色五月婷婷| 久久久久久久久久久44| 久久99操| 九九热精品6| 香蕉操亚洲| 天天日天天爽| 人妻aV在线| 综合婷婷六月| 综合99久久天天综合| 婷婷久久综合久| 日本nghangse中文字幕| 激情五月深爱五月| 久久9热| 少妇AB又爽又紧无码网站| 中文网婷婷字幕婷| 久久五月天黄色五月天色网址| 99热99艹在线观看| 久久99操| 色综合色色| 久久99激情丁香婷婷小说网| 久久久久亚洲AV无码网影音先锋| 337p大胆噜噜噜噜噜91Av| 五月婷婷啪啪| 综合性爱网| 九九自拍网| 欧美成人无码高清一区二区三区| 五月婷婷丁香五月 | 九九综合| 91聚色综合网| 色九月婷婷综合| 亚洲 五月 婷婷 成人| 丁香六月啪啪| 婷婷欧美激情综合| 色色色图| 99热草草| 狠狠狠人妻| 激情色播| 中文AV在线播放| 亚洲热久久| 色五月天.con| 五月丁香婷婷五月| 婷婷五月天成人视频| 亚州激情网| 久久综合干| 亚洲AV成人无码电影| 99热这里只有精品69| 成人va在线播放| 日本在线视频播放91| 99免费热视频在线| 丁香五月 性爱| 开心五月综合激情综合五月| 精国产品一区二区三区A片| 99噜噜噜在线播放| 久久草人妻| 99久久9| 久艹大香蕉| 开心婷婷中文字幕| 婷婷五月色情| 九月色婷婷综合| 无码色综合| 天天爱综合网| 99人人操人人操人人精| 99综合自拍| 久久色五月天| 综合99综合久久久久久久| 99re热在线视频观看| 婷婷娱乐丁香综合网| 丁香五月五月婷婷| 人人色性网| 午夜少妇在线观看视频| 大狠狠在线| 99热九九热| 色情婷婷| 五月婷婷五月天| 激情综合4月| 婷婷五月天网| 99色6爱9热| 亚洲精品亚洲人成人网| 夜夜夜夜做天天天做无码视频| 全部老头和老太XXXXX| 最新激情五月天| 婷婷丁香熟女| wwwC0maV五月花| 超碰久热| 无码毛片992367| 大香焦啪啪啪| 26uuu欧美| 天天爱天天爽| 精品久久99| 五月丁香色婷婷| 丁香五月天激情小说| 九月婷婷综合色干| 欧美成人色婷婷| 亚洲无码播放| A片试看50分钟做受视频| av中文网站| 九九热re99re6在线精品| 天天干狠狠| 久久一二三视频| 色九九九综合| 99热这里全是精品| 婷婷五月天影院| 国产精品久久久爽爽爽麻豆色哟哟 | 日本久久久97| 99啪啪视频| 丁香色啪综合| 九九热啪啪| 无码少妇高潮喷水A片免费| site:feetmall.com| 国产午夜精品一区二区| 激情五月婷| 久久伊人五月天| 超碰三级秋霞| 99热久久日本| 国产偷人爽久久久久久老妇APP| 亚洲精品视频在线播放| 五月天婷婷青青草| 五月天桃色深爱网| 婷婷爱五月天人人爱| 丝袜人妻| 亚洲乱啪| 天天操天天操天天操天天操天天操 | 狠狠色狠狠| 丁香婷五月| 色月九九| 欧美日本99| 色香蕉影院| 亚洲第一综合| 操一操| 99噜噜噜在线播放| 亚洲无码yw| 色九九综合色| 天天综合网站| 久热大香蕉| 日本一道久久| 日韩av网站在线观看| 97色在线| 美女网黄| 日韩欧美成人片| 色J香五月天| 久久一热| 99视频精品全部观看10| 五月丁香婷庭在线| 伍月激情天| 五月丁香综合久久夜夜| 亚洲成人AV高清字幕| 日本色五月| 无码99| 国产日韩亚洲欧美在线观看| 思思热在线精品视频网站| 五月色婷婷影视在线电影| 婷婷五月av| 五月天婷婷影院| 熟女91九色| 亚洲精品网址| 另类激情五| 91丨九色丨国产在线| 狠狠色噜噜狠狠亚洲A∨| 小香蕉av| 九色99视频| 1024AV视频| 久久精品凹凸分类| 97午夜一区二区| 97色精品视频 | 久久一二三视频| 婷婷六月丁香激情综合| 九九九九九九九热| 五月激情网络| 婷婷五月激情视频在线| 色五月综合在线| 五月激情婷婷丁香| 色婷婷天堂| 91黄操| 思思热视频| 五月天激情综合| 97色干| 色婷五月天| 99视频| www.91av.com| 97久久五月丁香婷婷| 天天肏高清在线| 人人操人人操919999| 九九色热| 色五月婷婷、老熟女| 激情五月婷婷色播网| 日操夜撸| 另类天堂| 成人超碰网| 97操碰日本女人| 日韩成人电影在线播放| 天天操夜夜爽天天操| 五月天婷婷色播在线网| 五月天激情婷婷久久| 激情六月婷| 欧洲不卡视频| 黑人糟蹋人妻HD中文字幕| 五月停亭久久电影| 九九色大香蕉| 丁香伊人综合| 五月婷六月丁香| 色五月丁香激情视频| 五月丁香久久丝袜啪啪| 91玖玖| 极品人妻XXXXOOOO| av激情在线| 五月丁香综合激情在线观看| av操一操| 另类激情中文| 伊人丁香五月婷婷潮吹| 激情婷婷丁香五月天小说| 天天爽综合| 日本91在线| 人妻少妇色综合| 狠狠一日| 亚洲婷婷丁香五月在线| 老司机伊人| 久久a热| 亚洲AV永久无码影院黑人| 婷婷欧美激情| 欧美婷婷五月激情| 久久人操| 99cao婷婷| 深爱五月月天| 国产性爱一级| 亚洲精品无码A片一区二区| www.婷婷五月天,com| 狠狠狠色激情综合适合| 少妇AB又爽又紧无码网站| 成人av在线网址| 天天操综合网站| 久热这里| 久久AAAA片一区二区| 婷婷综合五月天| XX色综合| 五月婷婷先锋| 婷婷瑟五月天久久综合| 六月色色| 大香蕉免费9| 蜜乳中文字| 国产又粗又大又爽又黄| 金桔一区二区ab地址| 色噜噜狠噜噜视频| 超碰婷婷五月| 热久久视频99| 开心婷婷五月| 夜夜躁狠狠 | 久操婷婷| 婷婷五月中文字幕| 丁香六月婷婷综合欧美| 影音先锋91在线资源站| 欧洲亚洲免费视频区| 91精品婷婷国产综合久久| 超碰人人操| 丁香五月六月婷婷怡红院| 99超超碰| 亚洲综合网激情小说| www狠狠| 另类图片色五月| 五月天桃色深爱网| 五月激情综合性爱| 五月婷婷,六月丁香| 国产精品 的国产| 蜜桃五月天色| 婷婷桃色网| 五月婷婷丁香av| 刘玥精品一区| 婷婷视频在线| 9|在线观看视频| 久久九九大香蕉电院| 九九久久9 9在线观看| 青青草深爱激情网| 99亚洲精品| 五月丁香六月婷精品视频| www色色com| 六月丁香射婷婷欧美色图片| 色婷婷成人做爰A片免费看网站 | 91久久久久久| 色天天狠狠干| 国产69久久久欧美黑人A片| 九九一综合精品| 又大又粗九一在线| AV天堂婷婷五月天| 狠狠九九婷婷韩| 99免费视频| 久热伊人| 五月天激情网图片| 快色t v在线入口| 丁香九色不卡aaa | 激情五月深爱五月| 日韩无码AV电影网站| 另类视频丁香五月| 九九精品亚洲| 日本一级一级一级一级| 婷婷的久久网站| 六月婷婷激情| 夜夜夜夜做天天天做无码视频| www.ywav| 免费AV在线| 桃色五月婷婷| 黄色中文字目| 五月丁香婷婷爱| 国产精品久久..4399| 精品一二三区久久AAA片| 婷婷操逼网| 婷婷丁香综合| 五月丁香五月综合欧美| 天天成人丁香美女AV| ...婷婷五月综合不卡,国产在线手机 | AV中文字幕夜夜操b天天摸bb | 日韩成人精品中文字幕电影| 五月天婷婷在线AN| 午夜色丁香| 五月丁香五月综合欧美| 爱的综合网| 狠狠色色综合| 色婷婷综合网| 色婷婷激情| 婷婷,五月天,丁香,第一| 成人国产网| 97干欧美| 欧美成人精品一区二区| 肏屄色播伊人97婷婷| 久久A极片| 先锋资源91| 久久精彩视频99| 91久久综合| 婷婷激情五月呦呦| 男人天堂99| 99热精品一| 成人丁香色| 激情综合网激情五月婷婷| 夜夜久久综合网| 国产综合激情五月久久| 久久99精品久久久久久噜噜| 九九色情网站| 色播五月婷婷| 免费观看的av| 丁香六月天婷婷开心综合| 色呦呦免费观看| 婷婷视频在线碰| 色综合五月| 五月婷婷之婷婷| 九九热视频免费观看| 色婷婷综合久久久久| 色婷婷AV久久| 国产亚洲精品AAAAAAA片 | 91日精品| 婷婷五月综合色小姐小说| 色五月婷婷网| 综合色五月| 26uuu精品国产| WWW.桔色成人.COM| 99色区| 亚洲av成人在线| 亚洲AV永久无码影院黑人| 亚洲成人影视在线| 色啪网| 婷婷色综合| WWW.17C亚洲精品| www色综合| 丁香5月啪啪| 亚洲 激情 中文| 激情色色| 91精品丝袜久久久久久| 激情綜合網址| 无码橾| 丁香六月亚洲| 九九99偷拍视频| 91夫妻视频| av高清无码| 色色99| 强辱丰满人妻HD中文字幕| 久久99热这里只有精品| 99思思| 91碰在线| 久热伊人| 大香蕉AV在线| 人人干人人看| 丁香午夜天| 天天干天天干天天| 夜夜骑夜夜撸| 91操碰| 色色激情五月天| 狠狠精品干练久久久无码中文字幕| 婷婷五月影院| 97色女人在线| 久久大香蕉| 亚洲天天| 在线观看免费视频| 日本强伦片中文字幕免费看| 免费黄网不卡AV| 99年操人人爽| 天堂网亚洲色图| 9色在线视频精品观看| 五月天基地| 大香蕉欧美在线| 久久久久亚洲AV成人无码电影| 大香蕉人在线65| 五月天堂色| 大功率国产在线| 六月五月久久丁香| 婷婷激情啪啪| 丁香五月欧美| 在线不卡视频| BBWCUCKOLD精品熟妇| 婷婷五月色| 九色成人AV在线| 国产精品美女久久久久AV超清| 日本视频不卡123区| 九九九激情网| 大香蕉中文| 中文字幕欧美久久| 亚洲精品国产成人AV在线| www.精品99| 一本伊人色婷| 欧美精品啪啪| 少妇综合网| 超碰国产一区| 999激情视频| 久久久久综合激动五月天| 激情宗合网激情五月天| 4399人妻无码久久久| 亚洲色婷婷五月天| 99精品久久久久久久久| 久久久久五月丁香| 久久9视频欧美| 婷婷五月天熟妇| 类似婷婷激情综合网站| 免费视频无码| WWW.久久久久久久久久久久久| 婷婷精品免费久久| 丁香婷婷六月天| 99在线精品视频| 色婷婷导航| 久热伊人在91| 九九热这里只有精品首页| 五月丁香婷婷成人综合网| 天天做天天摸| 九九aV| 久久机热探花| 日日日日做夜夜夜夜无码| www.婷婷五月| 高清无码网址| 婷婷丁香九月| 开心五月婷| 色屌丝中文字幕| 无码激情AAAAA片-区区| 亚洲超级碰| 婷婷五月 丁香六月| 丁香综合婷婷五月天| 欧美日韩成人在线| 91色涩| 五月婷婷五月天天| 九色视频91疯狂| 激情国产五月| 激情图片亚洲| 久热91精品| 日本三级第一页| 99热6这里只有精品6| 色婷另类| 五月婷婷9| 97婷婷丁香五月| 超碰AV在线| 欧美日韩成人在线免费| 五月丁香啪啪啪啪| 久久九九热视频| www.AV在线| 开心五月深爱五月丁香五月激情五月| 97色婷婷| 熟女激情网| 国产这里只有精品| 操91综合网| 五月婷人妻| 五月激情婷婷在线| 色99色| 天天干夜夜想| 91日综合欧美| 久久久婷婷色五月资源网| 成人做爰A片免费看视频| 另类激情五月| 14色综合婷婷| 欧美操综合| www.狠狠干com| 国产日产亚系列精品版优势| 久久婷婷五月天| 亚洲五月婷| 99热综合色图| 操逼巨乳91| 九伊人网| 婷婷综合网| 啪啪东京热| 人人草人| 色综合香蕉视频| 五月婷色激情五月| 婷婷五月天亚洲综合网| 五月激情五月婷婷五月天在线| 精品无码久久久久久久久| 热久久99视频| 99国产精品久久久久久久久久久| 第二色AⅤ| 九月丁香婷婷综合| 色久九| 久久五月视频| 丁香五月色| 色吧五月| 一个色的综合| 久久9热好| 丁香五月婷婷骚视屏| 丁香六月成人| 天天日天天爽夜夜爽| 九 九九九AV| 亭亭玉月丁香| 九九色色色| 色婷婷www| 五月天婷婷自拍图片在线观看| 色色婷婷五月| 中文字幕人成乱码在线观看| 日日日日做夜夜夜夜无码| 极品人妻VIDEOSSS人妻| 亚洲va欧美va国产综合久久久| 夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂亚洲亚洲亚洲亚洲亚洲亚洲亚洲亚洲色 | 亚洲亚洲人成综合网络| 色婷婷五月天成人网| 99热九九九九| 激情九九综合网| 青青草Avb在线| 婷婷五月天激情网| 欧美群妇大交乱婬网| 国产看真人毛片爱做A片| 亚州精品久久久久AV无码| 毛v一区二区视频| 成片免费播放| 99热精在线九九久久保| www.99.色| 狠狠色噜噜狠狠狠888| 亚洲人妻av| 婷婷五月欧美综合| 色色色色网| 五月天激情综合在线| 亚洲色图五月丁香| 婷婷六月丁香在线| 国产麻豆视频| 日本高清久| 婷婷综合网在线| 影院久久久| 日韩色色视频| 天天爽天天干天天| 色色五月天丁香| 中文字幕免费高清电视剧| 亚洲情欲| 天天色综合色色色色色。| 变态另类色图| 久碰视频| 性日本精品| 99操视频| cao视频,现在观看| 婷婷五月天社区| 欧美成人精品老美女噜噜噜| 日本精品99| 婷婷五月丁香激情| 欧美婷婷五月丁香| 婷婷五月天香蕉| 色五月综合网| 伊人热婷婷| 欧美性生交XXXXX无码小说| 青青草五月天| 99视频精品8 | 五月天激情久色| 9在线9在线婷婷在线国产| 五月激情小说| 99九九视频精彩在线| 色月视频| 亚洲五月天婷婷| 激情骚五月| 国产精产国品一二三在观看| 九九人人精品| 色青五月天| 热99精品视频在线观看| 欧洲S级在线观看| 九九99九九精品免费| 综合久久99| www.99热. com这里只有精品| 国产99美少妇| 五月婷婷偷拍| 激情五月婷婷色色| 99视频这里有精品| 久久精彩免费视频| 六月丁丁香| 少妇人妻综合色6699| 五月天天天开心激情网| 碰97久久| 综合爱久久| 伊人久久丁香狠狠婷婷综合香蕉| 丁香六月婷| 色婷婷免费观看| 五月激情六月宗合| 婷婷综合五月色播| 极品 少妇 内射| 婷婷五月丁香基地在线视频官网| 99热99美国在线观看| 中文幕无线码中文字蜜桃| 国产午夜一区二区三区| 婷婷五月香蕉| 欧洲色| 五月天婷婷色综合| 丁香五月天在线| 99热最新网址| 久香草视频在线观看| 狠狠操天天操综合| 五月激情婷婷图片基地| 国产超碰在线| 激情深爱五月婷婷| 91热在线| 九九综合色| 97干资源在线观看| 91fuliwang| 奇米影视在线视频| 亚洲AV无码成人电影| 久久人人添人人爽添人人片αV | 天堂色色色| 4399伦理午夜| 色婷婷在线电影| 色色五月婷婷网| 性爱技巧五月| 婷婷九月久久| 色玖玖网| 日韩视频女神99| 伊人大香蕉在线视频| 99热色精品| 日日操日日撸| 99久热| 色色激情| 中文字幕在线日亚洲9| 色婷婷婷婷| 国产精产国品一二三在观看| 日本少妇裸体做爰高潮片| 夫妇交换刺激做爰| 久久这里只有精品视频15 | 99久久久久| 久久五月综合| 青青青在线视频国产| 丁香五月欧美婷婷综合| 五他月天啪啪啪| 热久69| 亭亭色色五月天| 综合久久丁香婷婷,五月婷婷六月丁香,开心激情综合网,六月丁香在线观看,婷婷丁 | 色丁香五月天婷婷| 亚洲成人超碰| 99爱视频在线观看| 国产精品人成A片一区二区| 综合狠久久| 91打屁股视频网站| 五月天激情四射| 五月天欧美 另类小说| 六月丁香影院| 丁香五月综合激情性爱| 九九热在线观看视频| 人妻人人操| 99热精品中文字幕| 丁香六月激情综合| 婷婷九九色| 操逼巨乳91| 大香蕉久| 五月婷丁香亚洲| 这里精品| 特黄三级片| 丁香六月婷婷久久综合| 久九男女天堂| 天天综合色99| 激情五月天视频| 国产五月婷| 五月丁香啪综合| 日本操天堂| 久久久27操| 五月婷婷熟女| 久久香蕉丁香| 五月丁香欧美综合| 亚洲亚洲人成综合网络| 五月天怕怕| 99热99热在线观看| 色中色综合| 激情综合网激情五月天| 六月色 亚洲| 大香蕉九九| 99精品福利视频| 亚洲激情婷婷| 久久日本wwww色| 丁香六月狠狠| 99爱视频| 五月丁香黄色视频| 婷婷五月天丁香综合网| 丁香5月激情网| 五月婷婷亚洲综合网| 久久99久久99精品免观看粉嫩| 亚洲成av人影院| 99玖玖免费视频| 情涩婷婷五月天| 色五月av| 五月天婷婷激情网| 成人五月天在线视频在线观看| 狠狠99| 无码字幕中文| 97综合在线| 久久九九国产精品怡红院| 99亚洲精品综合在线| Av狠狠色丁香婷| 狠狠操狠狠插| WWW、99热| 欧美激情丁香五月天久久婷婷一区| 久热这里| 婷婷五月丁香综合瑟瑟| 婷婷的激情五月| 五月天天综合| 99在线视频喷水| 婷婷五月婷婷五月天| 婷婷99狠狠| av在线免费网站 | 婷婷五月天伊人网在线观看视频| 久热 91| 丁香五月婷婷天堂大香蕉| 九九热99精品| 亚洲国产无线乱码在线观看| 熟美女麻豆| 天天综合天天玩夜夜玩天天玩夜夜玩 | 天天肏高清在线| 九九精品在线网| 熟女人妻视频| 五月婷婷在线视频免费观看| 六月婷婷五月丁香| 伊人大香蕉综合在线| 激情婷婷五月社区| 激情久久伊人| 天干干夜夜操| 国产精品久久欧美久久一区| 久久这里这里有精品免费视频| 婷婷丁香在线播放| 婷婷情色开心五月天99| 天天肏天天插| 另类少妇人与禽zOZZ0性伦| 26UUU| 五月天色色网站| 天天色综和网| 久久精品99久久久久久| 久婷久婷激情肉| 色色免费网站| 亚洲成人网站在线| 久久思思热| 色婷婷伊人|