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

ARTICLE DETAIL

資訊詳情

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

C++11新特性實戰(zhàn):列表初始化、移動語義、lambda與function/bind

C++11新特性實戰(zhàn):列表初始化、移動語義、lambda與function/bind C11【第七篇】 ——— 列表初始化、移動語義、可變參數(shù)模板、lambda表達式、function包裝器和bind包裝器C11這批特性出來之后很多老代碼的回頭率真的低了不少。列表初始化、移動語義、可變參數(shù)模板、lambda、function、bind這幾個東西單獨拿出來每一個都能寫幾千字但日常開發(fā)里它們往往是一起出現(xiàn)的移動語義解決深層拷貝的痛lambda順手解決回調冗長的問題function和bind把各種可調用對象收編成統(tǒng)一類型可變參數(shù)模板在日志和工廠函數(shù)里直接省掉一坨重載。這篇作為C11系列第七篇默認你已經(jīng)有C98的使用基礎能看懂模板、類、左值右值的基本概念但對這批現(xiàn)代C特性還沒有系統(tǒng)梳理過。我會結合自己實際改代碼、寫庫、做框架時踩過的坑把每個語法的核心作用、底層邏輯和典型場景說透。1. 列表初始化C11給初始化方式立的規(guī)矩1.1 為什么一定要用花括號C98時代初始化方式散得離譜。數(shù)組有int arr[] {1,2,3};結構體可以Point p {1,2};單個變量既可以直接賦值int x 5;也可以用構造std::vectorint v(10);連指針初始化還分nullptr出來之前用NULL又是一堆坑。散亂意味著什么意味著代碼風格不統(tǒng)一意味著模板代碼想把任意類型初始化成一個值非常麻煩。C11給出的方案是統(tǒng)一花括號初始化列表初始化。不管是內置類型、數(shù)組、結構體、還是std::vector、std::map這種容器都可以用一對花括號把初始化列表寫清楚int x{ 5 }; int arr[]{ 1, 2, 3 }; Point p{ 1, 2 }; std::vectorint v{ 1, 2, 3, 4 }; std::mapstd::string, int m{ {a, 1}, {b, 2} };這個看似簡單的改動最大的意義在于讓初始化變成了“一種可以傳給模板和泛型代碼的語法結構”。我在寫泛型工廠時最直觀的感受就是以前要從一個參數(shù)列表去構造任意類型你得手寫一堆構造調用有了列表初始化和后面要講的可變參數(shù)模板一套代碼就能把任意類型任意參數(shù)的構造都接住這個收益是長期存在的。另外花括號初始化也在代碼風格上給出了極大的整潔度。團隊里只要規(guī)定“能用花括號初始化就盡量用”新老代碼的閱讀成本立刻下降這個對維護期的收益比很多人想象的大。1.2 initializer_list 與構造函數(shù)的“搶人大戰(zhàn)”花括號初始化背后依賴的核心類型是std::initializer_listT。當一個類定義了接受std::initializer_listT的構造函數(shù)時用花括號初始化它就會優(yōu)先走這條路徑class MyData { public: MyData(std::initializer_listint list) { std::cout initializer_list 構造, 元素數(shù)量 list.size() std::endl; } MyData(int a, int b) { std::cout (int, int) 構造 std::endl; } }; MyData d1{ 1, 2, 3 }; // 走 initializer_list MyData d2(1, 2); // 走 (int, int) MyData d3{ 1, 2 }; // 注意走 initializer_list 而不是 (int, int)這就是經(jīng)典坑點只要該類有 initializer_list 構造函數(shù)花括號初始化就優(yōu)先匹配它哪怕另一個普通構造函數(shù)匹配得“更精確”也不行。d3{1, 2}這種寫法很多人以為會走進(int, int)實際卻去了列表構造結果可能完全不一樣。這類問題在標準庫容器上表現(xiàn)得更加直接std::vectorint v1(10, 1); // 10個元素全部為1 std::vectorint v2{ 10, 1 }; // 2個元素分別是10和1v2這種寫法在代碼評審里經(jīng)常被年輕人拿來炫技但誤用也確實容易產(chǎn)生邏輯錯誤。生產(chǎn)環(huán)境下我更建議容器初始化明確的數(shù)據(jù)用花括號想要“填充n個值”這種語義就用圓括號別讓閱讀者猜。1.3 窄化轉換編譯期的安全檢查列表初始化另一個被低估的價值是禁止窄化轉換narrowing conversion。所謂窄化就是把一個高精度或大范圍的值隱式轉換成一個可能精度丟失或范圍縮小的類型。C98里這些都是默許的頂多出個警告但警告經(jīng)常被忽略double pi 3.14159; int a pi; // 編譯通過警告后靜默截斷 int b{ pi }; // 編譯錯誤double 到 int 是窄化轉換用花括號初始化時編譯器把這類轉換直接判為錯誤逼你顯式寫出意圖int b{ static_castint(pi) }; // 顯式轉換OK這個特性在維護大型項目時是個保護傘。我見過太多因為類型轉換丟精度產(chǎn)線上出事故的case罪魁禍首全是那些裸的隱式轉換?,F(xiàn)在不少現(xiàn)代代碼規(guī)范直接規(guī)定初始化必須用花括號顯式轉換必須用 static_cast兩者配合從源頭掐掉了一大批類型相關的隱蔽bug。唯一需要留意的是如果你在寫老代碼遷移一股腦全改成花括號初始化那編譯器會突然報出一堆“無法編譯”的錯這時候先別慌著用 static_cast 強行改回去要逐個確認那個窄化到底是有意還是無意往往能發(fā)現(xiàn)幾個之前被忽略的真實缺陷。2. 移動語義拷貝之外的第二條路2.1 右值引用到底在表達什么在C11之前左值右值的概念在語法層面只有“能不能取地址”這種粗糙的區(qū)分。C11引入右值引用之后我們可以寫一個專門接收“臨時對象”的接口臨時對象本質上是一個馬上要被銷毀的資源包這時再去深拷貝就是白白浪費性能。移動語義的精髓不是“快一點”而是“本來就不用復制”。右值引用理解上有個常見障礙它不是用來給變量“起一個右值的別名”的而是表示“這個東西是可以被掏空的臨時資源”。所以std::move的邏輯其實是把一個左值顯式地標注成“我允許你把它當臨時對象掏空”之后移動構造函數(shù)就會把資源指針直接拿過來把源對象置為空。class BigBuffer { public: BigBuffer(size_t size) : size_(size), data_(new char[size]) { memset(data_, 0, size); } // 拷貝構造深拷貝整塊內存 BigBuffer(const BigBuffer other) : size_(other.size_), data_(new char[other.size_]) { memcpy(data_, other.data_, size_); std::cout 拷貝構造被調用 std::endl; } // 移動構造直接接管指針 BigBuffer(BigBuffer other) noexcept : size_(other.size_), data_(other.data_) { other.data_ nullptr; other.size_ 0; std::cout 移動構造被調用 std::endl; } ~BigBuffer() { delete[] data_; } private: size_t size_; char* data_; };看這個BigBuffer的兩個構造拷貝構造要把整塊內存復制一份如果這塊內存是幾十MB一次深拷貝就是幾十MB的讀寫移動構造只是把指針從源對象手里拿過來再把源對象指針置空成本幾乎為零。這個差別在容器動態(tài)擴容、函數(shù)按值返回、中間臨時對象傳遞這些場景中是數(shù)量級的性能差異。2.2 移動賦值與“源對象被掏空”的紀律有移動構造自然就有移動賦值BigBuffer operator(BigBuffer other) noexcept { if (this ! other) { delete[] data_; data_ other.data_; size_ other.size_; other.data_ nullptr; other.size_ 0; } return *this; }注意這里必須先釋放自己原有的資源然后接管對方資源最后把對方置空。不釋放就接管會造成內存泄漏少了置空那一步則會導致源對象的析構函數(shù)把同一塊內存delete兩次直接觸發(fā)double-free問題。移動之后源對象處于“有效但未指定”的狀態(tài)標準要求它是可以安全析構、可以重新賦值的但你不能假設它里面還有原來的數(shù)據(jù)。我見過有人把std::move之后的源對象又拿去當普通變量用讀取到nullptr或者空字符串時一臉懵。所以誠實的做法是移動完一個對象后要么立即丟棄它要么明確把它重新初始化/賦值成可用的狀態(tài)。這里必須強調一個新手常見的幻覺移動語義并不是自動發(fā)生的它需要類本身定義移動構造函數(shù)/移動賦值。如果我們的BigBuffer只寫了拷貝構造沒有移動構造那么即使調用方把臨時對象std::move過來實際執(zhí)行的還是拷貝構造。很多性能敏感的代碼沒達到預期效果排查半天最后發(fā)現(xiàn)是類沒寫移動構造白白浪費了std::move的姿態(tài)。2.3 完美轉發(fā)std::forward 的正確用法模板編程中經(jīng)常遇到一個需求寫一個中間轉發(fā)函數(shù)把參數(shù)原樣轉給另一個函數(shù)并且要保留參數(shù)的左值/右值屬性——如果原來是左值繼續(xù)當左值傳過去如果是右值就保持右值屬性讓目標函數(shù)能夠移動它。這就是完美轉發(fā)。轉發(fā)引用也叫萬能引用的寫法是T它只在模板推導環(huán)境下成立templatetypename T void Relay(T arg) { // 這里如果直接傳 arg會丟失右值屬性 Process(std::forwardT(arg)); }std::forwardT的作用是根據(jù)T的推導類型來決定把arg轉換成左值還是右值。如果調用Relay時傳進來的是右值臨時對象T會被推導成某個具體類型forward就會把arg重新轉回右值引用讓下游能用移動語義接管它如果傳進來的是左值T推導成左值引用forward就原樣以左值傳遞。我在實現(xiàn)一些“軟件總線”式的中轉模塊時經(jīng)常用這個手法一個函數(shù)接收任意類型任意數(shù)量的參數(shù)然后轉發(fā)給真正處理請求的對象。不用完美轉發(fā)的話參數(shù)每經(jīng)過一層中轉都會損失類型信息臨時對象被迫退化成拷貝性能在多層轉發(fā)后會累積惡化。3. 可變參數(shù)模板編譯期的參數(shù)“打包”和“拆包”3.1 參數(shù)包怎么定義和展開可變參數(shù)模板讓函數(shù)和類可以接受任意數(shù)量、任意類型的參數(shù)。這在C98里只能靠重載或者va_list這種類型不安全的方式實現(xiàn)而在C11里參數(shù)的類型安全由編譯器保證。定義一個可變參數(shù)模板函數(shù)最基本的樣子templatetypename T void PrintOne(T value) { std::cout value std::endl; } templatetypename T, typename... Args void PrintMany(T first, Args... rest) { std::cout first ; PrintMany(rest...); }Args是一個模板參數(shù)包rest是一個函數(shù)參數(shù)包。rest...這個語法叫參數(shù)包展開把當前函數(shù)收到的剩余參數(shù)逐個展開再去調用下一層。整個遞歸過程會在參數(shù)包為空時落到那個單參數(shù)的重載上形成終止條件。很多初學者剛看到這個遞歸會覺得恐怖其實它就是編譯器在編譯期做了N層實例化每一層削掉一個參數(shù)直到削光。每個不同的參數(shù)組合都會生成一個獨立的函數(shù)實例所以如果調用方參數(shù)類型很多模板實例化數(shù)量也會增加編譯時間變長。但換來的是運行時的絕對高效——所有參數(shù)處理都發(fā)生在編譯期運行時沒有一個額外的分支判斷。sizeof...可以在不遞歸的情況下直接獲得參數(shù)個數(shù)templatetypename... Args void CountArgs(Args... args) { std::cout 模板參數(shù)個數(shù) sizeof...(Args) std::endl; std::cout 運行時參數(shù)個數(shù) sizeof...(args) std::endl; }這個操作符在遞歸展開前做數(shù)量判斷非常有用可以提前剪枝一些特化分支。3.2 遞歸展開最常見的套路可變參數(shù)模板最樸素的用法就是一個“處理一個剩下的交給下一層”的遞歸展開。上面打印的例子就是這樣的但實際項目中我更多用它做日志系統(tǒng)。比如寫一個能把任意類型任意數(shù)量參數(shù)拼進一條日志消息的工具class Logger { public: templatetypename... Args void Log(Args... args) { std::ostringstream oss; Append(oss, std::forwardArgs(args)...); WriteLine(oss.str()); } private: templatetypename T void Append(std::ostringstream oss, T value) { oss std::forwardT(value); } templatetypename T, typename... Args void Append(std::ostringstream oss, T first, Args... rest) { oss std::forwardT(first); Append(oss, std::forwardArgs(rest)...); } };這里我特意用了Args...轉發(fā)引用保證傳入的臨時字符串在拼日志時不會經(jīng)歷不必要的拷貝。日志系統(tǒng)往往處在高頻路徑上這類微小的性能優(yōu)化在實際壓測中是能看出來的。使用遞歸展開要注意一個細節(jié)遞歸調用必須用rest...把剩下的參數(shù)展開少寫一個省略號編譯器會立刻報錯“參數(shù)包必須至少展開到一個參數(shù)”。錯誤信息比較長新手容易慌其實核心就是檢查省略號位置。另外終止重載有條件是不能依賴運行時判斷的必須是編譯期的結構——要么用重載特化要么用if constexprC17的解決方案C11下比較穩(wěn)妥的辦法就是用重載或者偏特化來終止。3.3 逗號表達式展開不用遞歸的另一種方案遞歸展開思路清晰但每到N層參數(shù)就要實例化N個函數(shù)編譯時間會變成負擔。還有一種更緊湊的展開語法利用逗號表達式和初始化列表一次性把參數(shù)全部處理完templatetypename... Args void PrintAll(Args... args) { int dummy[] { (std::cout args, 0)... }; (void)dummy; }拆開看(std::cout args, 0)是一個逗號表達式——先執(zhí)行std::cout args再把0作為整個表達式的值。然后對這個表達式做參數(shù)包展開得到的實際是int dummy[] { (std::cout arg1, 0), (std::cout arg2, 0), ..., 0 };因為std::cout arg1返回的還是流對象不是int為了湊出數(shù)組元素類型為int用逗號表達式的0來兜底。這個技巧不必搞得花里胡哨但確實在一些空格分隔、不分層的場景比如把多個字符串直接拼進一個緩沖區(qū)里比遞歸更簡潔也省了一次次實例化遞歸殼子的開銷。我還見過一種變體是用std::initializer_listint{ (fun(args), 0)... }來展開效果類似。不管哪種寫法核心都是“用逗號表達式把真正的參數(shù)操作變成數(shù)組初始化表達式列表”這是C11時代沒有折疊表達式時的經(jīng)典套路。到C17之后折疊表達式(std::cout ... args)直接把這個場景簡化成一行但如果你的項目還鎖在C11標準這兩種展開方式就得熟練掌握。4. Lambda表達式就地定義一個匿名函數(shù)對象4.1 完整語法和默認行為lambda表達式提供了一種就地定義匿名函數(shù)對象的方式常見的完整語法長這樣[捕獲列表](參數(shù)列表) mutable - 返回類型 { 函數(shù)體 };最簡化形態(tài)甚至可以省略圓括號和返回類型比如auto f [] { std::cout hello std::endl; }; auto add [](int a, int b) { return a b; };返回類型在函數(shù)體只有一個return時一般可以靠auto推斷但如果函數(shù)體內多處返回不同類型的值或者類型比較復雜就需要顯式寫上尾置返回類型auto transform [](const std::string s) - int { return static_castint(s.size()); };關于mutable關鍵字有個容易混淆的點lambda的默認行為是捕獲列表里的值拷貝并且在lambda體內是只讀的。想修改拷貝進來的變量必須加mutableint count 0; auto counter [count]() mutable { return count; }; counter(); // 1 counter(); // 2 std::cout count; // 仍然是 0說明改的是lambda內部拷貝的值不加mutablecount這行會直接編譯報錯。很多人看到這個報錯第一反應是“是不是lambda不能修改外部變量”其實是忘了它是只讀語義。4.2 捕獲方式的選擇值、引用、混合捕獲捕獲列表是lambda的靈魂也是最容易產(chǎn)生生命周期bug的地方。幾種寫法各有適用場景[value]按值捕獲lambda內部持有外部變量的拷貝。[ref]按引用捕獲lambda內部持有的是外部變量的引用。[]默認按值捕獲所有使用到的變量。[]默認按引用捕獲所有使用到的變量。[, flag]混合捕獲flag用引用其余按值。按值捕獲看起來安全但要注意它拷貝的是“捕獲時刻”的變量快照。下面這段代碼是經(jīng)典陷阱std::functionvoid(int) funcs[5]; for (int i 0; i 5; i) { funcs[i] [i](int x) { return x i; }; // OKi按值捕獲每個lambda有自己的i快照 }如果把[i]寫成[]或者[i]那么所有l(wèi)ambda共享同一個i變量的引用循環(huán)結束后 i 的值是5所有l(wèi)ambda再執(zhí)行時拿到的都是5。這個錯誤在“循環(huán)里注冊回調”的場景中幾乎人人都會踩一腳而且非常隱蔽因為編譯毫無問題只有運行時行為不對。另一類生命周期問題是引用捕獲局部對象。比如有一個函數(shù)創(chuàng)建了一個局部對象然后返回一個捕獲了該對象引用的lambdastd::functionint() MakeFunctor() { int v 42; return [v]() { return v; }; // 引用懸空函數(shù)結束后v已銷毀 }這種代碼就是未定義行為。正確做法是按值捕獲[v]或者把局部對象放到堆上并用std::shared_ptr管理后讓lambda捕獲智能指針的拷貝。我在代碼評審中見過好幾例類似寫法全是抱著僥幸心理覺得“這個函數(shù)應該不會很快返回吧”結果程序運行一段時間后偶發(fā)亂值排錯成本遠超寫代碼成本。4.3 lambda在STL算法中的實戰(zhàn)lambda在C11里最大的用武之地是配合algorithm頭文件里的算法。以前寫std::sort要定義一個比較函數(shù)或者函數(shù)對象// C98風格 bool CmpDesc(int a, int b) { return a b; } std::sort(v.begin(), v.end(), CmpDesc);有了lambda之后std::sort(v.begin(), v.end(), [](int a, int b) { return a b; }); std::vectorint nums{ 5, 3, 8, 1, 9 }; int threshold 5; auto count std::count_if(nums.begin(), nums.end(), [threshold](int x) { return x threshold; });這種寫法把邏輯直接放到使用處既避免了“函數(shù)定義和使用地點分離導致的上下文割裂”又天然支持捕獲外部變量比函數(shù)對象寫起來緊湊得多。我習慣把lambda用在項目里的這些高頻場景做排序、查找、過濾的自定義謂詞作為事件回調、定時器的處理函數(shù)延遲執(zhí)行一小段邏輯比如保存到資源析構時才執(zhí)行的清理動作配合std::function做接口統(tǒng)一的策略回調。使用lambda時最好遵循一個原則lambda函數(shù)體不要寫太長。正常四五行的邏輯是最舒服的如果超過十幾行說明這段邏輯值得提取成一個具名函數(shù)或成員函數(shù)否則代碼的可讀性會因為“嵌套在一堆算法調用里的匿名邏輯”而急劇下降。5. function包裝器把可調用對象統(tǒng)一收納5.1 std::function 的使用與類型擦除std::function是一個通用多態(tài)函數(shù)包裝器它可以存儲、復制、調用任何可調用對象包括普通函數(shù)、函數(shù)指針、lambda表達式、函數(shù)對象以及用std::bind生成的綁定對象。它的核心價值在于用一個統(tǒng)一的類型去表示“具有特定簽名的可調用操作”。#include functional std::functionint(int, int) op; op [](int a, int b) { return a b; }; // lambda op [](int a, int b) { return a * b; }; // 換個lambda op std::multipliesint(); // 函數(shù)對象 op MyFunc; // 普通函數(shù)這個能力背后是類型擦除機制。簡單說std::function內部維護了一個抽象基類和一個具體的包裝類模板模板里面保存著原始可調用對象的副本同時實現(xiàn)了統(tǒng)一的調用接口operator()。外部只看到std::functionint(int,int)這樣一個明確的簽名不知道里面到底存的是函數(shù)指針、lambda還是函數(shù)對象。這個過程有點像“把所有形狀各異的插頭插到一個萬能插座上對外只暴露同一個三相插口”。在實際工程里std::function最大的意義在于把回調注冊、策略注入、事件分發(fā)這些場景的可調用對象類型全部統(tǒng)一了。比如一個按鈕的點擊事件回調你既可以注冊一個成員函數(shù)通過bind也可以注冊一個lambda外部存儲的都是std::functionvoid()。5.2 回調場景下的正確姿勢我重構過一些把裸函數(shù)指針作為回調參數(shù)的舊模塊最大的痛點就是函數(shù)指針無法捕獲狀態(tài)。你想傳一個“帶業(yè)務上下文”的回調只能通過void* user_data再傳一個裸指針各種生命周期隱患。有了std::function之后業(yè)務數(shù)據(jù)可以直接被lambda捕獲根本不需要void*這種極度不安全的通道。真實模塊里經(jīng)常是這樣的class EventDispatcher { public: using Handler std::functionvoid(const Event); void RegisterHandler(int eventType, Handler handler) { handlers_[eventType].push_back(std::move(handler)); } void Dispatch(int eventType, const Event evt) { auto it handlers_.find(eventType); if (it ! handlers_.end()) { for (auto h : it-second) { h(evt); } } } private: std::unordered_mapint, std::vectorHandler handlers_; };這個模式在各語言里都很常見C11以前要實現(xiàn)得費不少勁現(xiàn)在用std::function幾行搞定。注意我在RegisterHandler里用了std::move(handler)因為std::function內部保存的是可調用對象的副本這步能省一次深度拷貝。5.3 function 的性能與坑std::function性能上確實有開銷核心是間接調用和可能的堆分配。它內部存儲可調用對象的副本如果可調用對象小比如無捕獲的lambda等同于一個函數(shù)指針很多實現(xiàn)在棧上通過小對象優(yōu)化就直接存了但如果捕獲了大量狀態(tài)的lambda體積大就可能觸發(fā)動態(tài)內存分配。我在做高頻回調系統(tǒng)時實測過用裸函數(shù)指針一次間接調用幾納秒到幾十納秒std::function會有額外幾納秒到幾十納秒的開銷。在真正的熱路徑比如每幀幾十萬次回調上這個開銷會被放大這時要么換裸函數(shù)指針要么用更輕量的專用回調類型。另一個坑是拷貝std::function的開銷。std::function是可拷貝的但拷貝一個里面裝了很大lambda的std::function等于拷貝了那份捕獲狀態(tài)。所以函數(shù)傳參和注冊時優(yōu)先用const std::function...接收內部需要保存時再拷貝或std::move別動不動作值傳遞// 不推薦 void RegisterCallback(std::functionvoid() cb) { callbacks_.push_back(cb); // 至少一次拷貝 } // 推薦 void RegisterCallback(const std::functionvoid() cb) { callbacks_.push_back(cb); } // 或者右值版本 void RegisterCallback(std::functionvoid() cb) { callbacks_.push_back(std::move(cb)); }如果某個std::function永遠沒有被調用但它的捕獲對象很大那么這個對象就一直占著內存直到std::function被銷毀或重新賦值。一些長生命周期的事件表容易在不知不覺中累積大量捕獲上下文排查內存占用時記得檢查std::function的捕獲體量。6. bind包裝器把函數(shù)參數(shù)“提前預定”出新的可調用對象6.1 std::bind 的基本操作std::bind用來生成一個“綁定了一部分參數(shù)”的新可調用對象它把事情分成兩半一半在處理函數(shù)定義完之后就已知另一半留給真正調用時再傳。#include functional int Add(int a, int b) { return a b; } using namespace std::placeholders; auto add5 std::bind(Add, 5, _1); std::cout add5(3) std::endl; // 輸出8等價于 Add(5, 3) auto add5and10 std::bind(Add, 5, 10); std::cout add5and10() std::endl; // 輸出15參數(shù)全部綁定調用時無需傳參_1、_2這些是占位符表示“這個位置留給調用時傳入的第一個、第二個參數(shù)”。占位符放在第幾個位置就代表調用傳入的參數(shù)填到對應位置。利用這個機制還可以調整參數(shù)順序auto swapAdd std::bind(Add, _2, _1); std::cout swapAdd(3, 4) std::endl; // 等價于 Add(4, 3)輸出7這個“參數(shù)重排”能力在適配第三方接口時非常實用。比如一個消息處理器的回調簽名是void Handle(int msgType, int priority, const Message msg)而你的處理函數(shù)只關心 priority 不為0的消息并且你的處理函數(shù)簽名是void Process(const Message msg)可以直接auto binder std::bind(Processor::Process, processor, std::placeholders::_3); // 只取第3個參數(shù)傳給Process6.2 綁定成員函數(shù)和對引用的處理綁定成員函數(shù)是std::bind的高頻用法。成員函數(shù)隱含第一個參數(shù)是對象本身所以Processor::Process后面要么接對象指針要么接對象引用或拷貝Processor processor; auto binder std::bind(Processor::Process, processor, std::placeholders::_1); // 或者 auto binder2 std::bind(Processor::Process, processor, std::placeholders::_1); // 按值拷貝對象注意大對象拷貝開銷我個人的習慣是對象生命周期明確長于回調時用processor綁定不確定生命周期時優(yōu)先考慮std::shared_ptrProcessor的拷貝加std::bind的占位策略甚至直接改用lambda捕獲智能指針更直白。綁定引用參數(shù)時有個隱蔽坑std::bind默認按值保存綁定參數(shù)。如果函數(shù)參數(shù)是引用類型直接 bind 一個變量進去實際綁定的是它的拷貝函數(shù)內部改引用不會影響原變量。想要綁定真正的引用必須使用std::refvoid UpdateCount(int n) { n 10; } int count 0; auto binder std::bind(UpdateCount, count); // 按值綁定改了沒反應 auto binderRef std::bind(UpdateCount, std::ref(count)); // 綁定真實引用 binder(); binderRef(); std::cout count; // 輸出10binderRef那次修改生效了std::ref返回一個引用包裝器這是一個C11里看起來簡單但使用頻率不低的工具。凡是需要把引用“當值”傳遞的場景包括std::thread、std::bind、std::function的捕獲都必須靠它來表達引用語義。6.3 bind 和 lambda 該怎么選很多人糾結std::bind和lambda哪一個更好。我的結論非常直接C11項目里能用lambda的地方優(yōu)先用lambda只有在確實需要參數(shù)重排、或者一些極其簡單的綁定場景才考慮bind。原因有三方面。第一lambda語法更直觀可讀性更好[processor](int x){ processor.Process(x); }一眼能看懂捕獲了誰調用了誰而std::bind(Processor::Process, processor, _1)對不熟悉bind的人來說還要反應一下。第二lambda的捕獲是顯式的[]、[]、[a]而bind是隱式按值保存在內部包裝對象里排查生命周期問題時lambda更直觀。第三編譯器對普通lambda的優(yōu)化能力比對std::bind生成的復雜包裝對象更強內聯(lián)概率更高。但 bind 并不是完全沒有價值。在某些需要真正“參數(shù)重排”的適配場景或者早期C11代碼風格已經(jīng)在團隊里形成慣例的項目里bind依然是可讀的。而且std::bind和std::function配合得相當自然std::functionvoid(int) callback std::bind(Processor::Process, processor, _1);在C14、C17之后泛型lambda和更高階特性的引入讓 bind 的使用場景更少了但如果你的項目還被鎖在C11標準bind 仍然是所有標準庫容器和類接口里的“一等公民”該會還得會。7. 常見問題與排查技巧實錄實際代碼中把這些特性組合使用踩坑的概率并不低。我把這幾年見過的高頻問題整理成一組速查方便大家對照。問題現(xiàn)象根本原因排查思路與修復花括號初始化導致窄化編譯錯誤int x{doubleVal}被禁止窄化顯式static_castint或者改用圓括號初始化如果確實需要舊行為深拷貝意外發(fā)生性能突然下降類沒有定義移動構造/移動賦值或者傳參時忘了std::move檢查類是否有noexcept移動構造檢查熱路徑上的拷貝調用循環(huán)內注冊的lambda回調值全部相同引用捕獲了循環(huán)變量變量最終是同一個終值改按值捕獲[i]或拷貝一份局部臨時變量再捕獲lambda按引用捕獲的對象已銷毀局部變量生命周期結束引用懸空按值捕獲或者把對象生命周期延長到堆上并用智能指針接管可變參數(shù)模板遞歸沒有終止重載缺少單參數(shù)版或者特化像PrintMany例子那樣補一個templatetypename T void Print(T)作為終止std::bind綁定引用參數(shù)但外部值不改變bind默認按值保存參數(shù)用std::ref顯式包裝引用std::function頻繁拷貝導致卡頓大捕獲狀態(tài)的function被反復按值傳遞函數(shù)參數(shù)用const std::function...接收存儲時std::move7.1 初始化相關的坑列表初始化最大的兩個坑是窄化轉換和initializer_list的優(yōu)先級。窄化轉換編譯錯誤一般不難定位關鍵是要定好項目規(guī)范在需要強制類型安全的代碼路徑上統(tǒng)一用花括號初始化。initializer_list的優(yōu)先級問題則更難防我的經(jīng)驗是凡是定義了initializer_list構造函數(shù)的類在代碼評審時要特意檢查所有{}初始化的位置確認確實是想走列表構造而不是普通構造。標準庫里std::vector、std::map、std::list都有這種行為稍不留神就會把“構造10個元素”寫成“構造1個元素內容為10”。7.2 lambda捕獲引發(fā)的懸空引用lambda捕獲問題的根源是生命周期管理。值捕獲雖然安全但也有代價捕獲了超大對象的lambda一旦存入std::function那個對象就一直被持有到function銷毀。如果這個function被存進全局容器那就是隱形的內存占用。我在實現(xiàn)定時任務系統(tǒng)時遇到過一個案例定時器回調捕獲了一個幾十MB的配置對象結果這個定時器對象一直存放在調度表里幾十MB內存被白白占著。后來改成捕獲std::shared_ptrConfig的拷貝并且在回調完成時從調度表移除問題才解除。7.3 可變參數(shù)模板遞歸不終止遞歸展開的模板如果不加終止條件編譯器會無限遞歸實例化下去最終報錯信息里會出現(xiàn)recursively required from 函數(shù)名...展開的模板list一長串看得人頭皮發(fā)麻。排查方法很簡單從報錯信息里找到最內層那個沒有終止重載的調用點補上單參數(shù)版本或者空參數(shù)版本即可。另一種不易察覺的問題是遞歸展開的每一次實例化都會在二進制里產(chǎn)生一個真實存在的函數(shù)符號參數(shù)多、調用頻繁時二進制膨脹和編譯時間上漲都能感覺到。如果對編譯期性能敏感盡快考慮C17的折疊表達式或者C11下的逗號表達式展開方案。7.4 移動語義相關坑移動之后的源對象問題我在代碼評審時看到過的錯誤包括移動后直接使用源對象的成員沒檢查空指針、移動賦值之前沒有釋放原資源造成泄漏、移動構造函數(shù)忘了noexcept導致 vector 擴容時退化為拷貝、以及無代價地把一個左值std::move進一個馬上還要用的地方。針對這些比較實際的規(guī)約是移動構造函數(shù)和移動賦值必須標注noexcept否則標準庫容器擴容時可能會改用拷貝而不是移動性能收益直接歸零。移動后的源對象要約定“視為懸空”除了重新賦值和析構不要讀它的成員。std::move不是“強制搬移”它只是把左值標記成“可供搬移”。最終是否搬移取決于目標類型有沒有移動構造/移動賦值。7.5 function/bind的坑std::bind與std::function組合的坑通常出現(xiàn)在捕獲生命周期上。由于 bind 在存儲被綁定參數(shù)時默認按值因此如果你在函數(shù)里 bind 了一個局部變量并把這個綁定器存到全局局部變量雖然已經(jīng)銷毀但 bind 內部保存的副本還在——這其實是安全的。真正不安全的是綁定了一個std::ref(localVar)因為那保存的是真實引用如果局部變量沒了引用就懸空。這種懸空與lambda引用捕獲懸空是同一個本質問題。排查引用懸空類bug時優(yōu)先懷疑兩處lambda的[]/[var]捕獲以及 bind 里的std::ref。另外一個容易被忽略的點是std::function的賦值與默認狀態(tài)。未賦值的std::function是空的調用它時拋std::bad_function_call。在多線程回調注冊場景里先判斷if (handler)再做調用是必要的防御但真正安全的長效方案是在回調注冊/注銷時加鎖管理避免同一個handler在執(zhí)行中被另一個線程替換或清空。8. 個人經(jīng)驗這幾個特性組合起來才是真香單獨看列表初始化、移動語義、可變參數(shù)模板、lambda、function、bind每個都是“獨立的新語法”但在實際工程里它們經(jīng)常是擰在一起用的。我在寫一個輕量級的消息總線模塊時這種合力體現(xiàn)得最明顯消息總線的注冊接口需要支持各種類型的事件處理器。事件處理器的類型不一樣有的是普通函數(shù)有的是成員函數(shù)有的是lambda怎么辦用std::function統(tǒng)一存儲配合bind把成員函數(shù)轉成std::function配合lambda捕獲業(yè)務上下文。事件對象的構造用列表初始化加可變參數(shù)模板一條消息的參數(shù)可以全部打包進一個對象。消息發(fā)送時用移動語義把消息對象直接交給下一個模塊避免大數(shù)據(jù)拷貝。整套代碼下來比起以前C98的實現(xiàn)既簡短又清晰性能還更好。如果非要說一個最值得優(yōu)先掌握的組合我建議把“l(fā)ambda std::function 移動語義”這組先練熟。它們能覆蓋日常80%的回調與策略場景而且思考方式可以遷移到C14、C17甚至C20的后續(xù)特性上??勺儏?shù)模板和完美轉發(fā)屬于模板庫作者級能力學習曲線稍微陡一點但理解了“編譯期參數(shù)打包/拆包”這個模型之后再去看std::tuple、std::make_unique這些標準庫實現(xiàn)的源碼會有豁然開朗的感覺。我自己的經(jīng)驗里還有一個很實際的小技巧在調試模板相關的問題時編譯錯誤信息通常特別長千萬別從上往下掃直接翻到最底部的note:或者error:那一行往往才是真正的錯誤源頭。配合這些新特性時代碼風格上建議定義一套固定寫法初始化盡量用花括號移動構造/移動賦值寫noexceptlambda捕獲值顯式寫出function作為回調類型統(tǒng)一用別名。時間久了你會發(fā)現(xiàn)這批特性不光是語法糖它們確實讓C代碼寫起來更接近“描述意圖”而不是“描述每一步操作”這也是C11最大的價值所在。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
99热资源在线| 五月天成人小说| 激情都市另类| 超碰成人电影| 少妇人妻人伦A片| sS丁香五月婷婷| www.五月婷| 五月丁香婷婷综合网| 丁香六月情| 国产激情综合五月| 亚洲中文字幕av| 色就色94欧美setu| 99久久国产宗和精品1上映| 日日操夜夜爽| 婷婷在线激情| 99热这里只有精品青草| 久久久久久人妻久久久久久久久久人妻久久久| 五月天色官网| 丁香五月六月婷婷自拍| 立川无码av| 4399高清无码视频| 日韩国产在线免费观看| 色婷婷影音| A短视频免费在线观看| 操操天堂| 夜夜资源站| 激情九月婷婷九月| 激情开心五月天| 在线观看亚洲视频影院| 国产精品日日躁夜夜躁| 深爱激情五月天| 丁香五月天网友自拍啪啪啪视频| 人妻精品久久久久久久| 亚洲国产va| 激情精品久久| 六月婷婷色五月| 五月丁香日本一抹本| 99ri精品在线| 丁香五月综合激情性爱 | 久久婷婷的综合色丁香五月| 另类亚洲电影| 激情久久婷婷| 强伦轩人妻一区二区电影| www.1024久久| 国产精品国产| 日韩亚洲视频| 99热这里只有精品国产免费| 人人干Av| 五月婷婷香| 99在线亚洲| 色欲色香伊人| 热久久91| 色播五月丁香| 97超级碰| 超碰爱爱爱| 密臀av无码人妻精品| 99啪在线| 大香蕉AV在线| 天天干天天 亚洲| 内射激情在线| 色五月天成人| 亚洲中文字幕网| 婷婷综合激情| 色婷网站| 色综合丁香婷婷| 99riAV国产精品视频| 大香蕉天堂| 成人国产综合| 丁香花五月天| 天天操天天插| 综合激情婷婷| Caoporn公开| 《丁香激情综合久久伊人久久》影视在线观看 -高清预告手机免费播放 -三妹影院 | 99热碰碰| 蜜桃婷婷五月| 婷婷色五月天在线观看| 伊人久久99| 操99| 亚洲另类AV| 伊人久久大香线蕉av一区| 色欲五月婷婷| 99性爱无码| 日日爽天天| 欧美色婷婷| 成人短视频在线| 五月花激情| 狠狠色综合网| Caop在线| 亚洲第一色色色色| 色私五月婷婷| 丁香五月天成人| 五月激情久久| 日韩一区二区在线播放| 丰满人妻一区二区三区| 亚洲婷婷五月天| 丁香五月综合网| 伊人九九综合| 婷婷五月免费观看| 91人人爽狠狠狠| 免费看欧美成人A片无码| 亚韩精品视频1区| 久七香蕉| 丁香五月色五月婷婷宗合| 五月丁香六月玩女人| 色五月首页| 久99999热视频在线观看免费| 九九久久玖玖爱| 五月丁香六月激情综合| 五月丁香无码| 九九色综合| 秋霞丝袜啪啪啪| site:pzdcoin.com| 久热一本| 99久久五月丁香野外| 婷婷五月天丁香花| 开心婷婷五月| 色综合久久久无码中文字幕999| 五月天久久网站| 色亚洲中文| 天天拍天天操| 色在线免费观看| 永久思思热在线| 五月天狠狠| 色婷婷电影网| 激情五月婷婷| enecarbon-materials.com污K127封锁请涟系@wip1688 | 97精品人人A片免费看| 91色吧网| 99久在线精品99re8热| 26uuu欧美| 欧美人人超级碰| 婷婷在线五月天观看| 天天干,天天日| 午夜丁香婷婷| www.色婷婷.com| 午夜天堂一区人妻| 丁香五月六月久久综合 | caopeng超碰| 伊人五月综合网| 八戒青柠影视剧在线观看 | 色五月色五天免费视频| 成人AV片播放| 这里只有免费的精品| 婷婷导航| 热99国产精品| 久久婷婷综合五月天| 综合 蜜月 婷婷| 丁香五月狠狠综合欧美| 国产毛多水多女人A片| 人人97碰| 久九色| 九九美女视频| 99乱视频| 任你干嘛免费视频播放| 人妻久久久久久| 国内9l视频自拍老熟女九色| 久色资源网| 香蕉久久国产AV一区二区| 国产精品久久99| 高潮毛片遮挡费高一百度| 亚洲综合另类| 天天色图| 这里只有精品免费视频| 亚洲AV无码成人精品电影| 丁香五月亭亭六月综合激情网| 国产成人精品一区二三区熟女在线 | 狠狠色噜噜狠狠狠狠综合| 国产婷婷五月天| 中文字幕免费高清电视剧| 99婷婷五月天| 久久在线视频免费观看| 99视频在线观看视频| 中文字幕精品无码一区二区| 99视频这里只有久久精品 | 综合久久婷婷五月丁香| 依人大香蕉| 色色精品色| 成人短视频在线观看| www.婷婷五月天.com| 激情五月天丁香| 丁香婷婷黄网站| 亚洲丁香花色| 日韩一区二区三区无码| 亚洲AV无码成人电影| 青青福利网| 色婷婷激情Av久久久| 韩国久久少妇视屏| 丁香激情五月少妇| 婷婷九月| 九九Av| 97五月天婷婷午夜| 色噜婷婷| 另类视频综合| 人人摸人人射| 1区2区视频| 日本99在线| 六月丁香大香蕉| 激情五月婷| 国产九月婷婷| 激情综合网五月激情| 色情性爱视频网址| 99热在线极品极品| 久久狼人天堂| 亚洲中文乱字字幕线在永久| 99热精品99| 79精品视频在线观看,| 激情五月婷黄版| 欧美三级A做爰在线观看| 婷婷五月天论坛| 在线成人av播放| 色99在线观看| 久久机热思思热| 玖玖精品婷婷| 蜜桃成语时李时珍 免费| 亚洲天天综合| 久久婷婷五月激情综合| 人妻aV在线| 色五月天影视| 亚洲天堂碰碰婷婷| 色色婷婷五月| 五月丁香六月婷婷色情| 人色五月天婷婷| 色色丁香色五月| 伊人久久艹| 丁香五月成人论坛| 五月天婷婷基地综合网| av在线婷婷| 欧美激情综合色综合啪啪五月| 六月激情久久婷婷| 成人毛片在线免费观看| 五月丁香花成人社区| 2020日日干| 秋霞午夜理论| av色婷婷| 欧美123区免| 开心五月激情网| 色爱终和网| 99操中文视频| 五月综合激情图片| 免费视频WWW在线观看网站| 另类小说五月天| 婷婷中文字幕版| 91免费看片| 四季8848精品成人免费网站| www.99热| 色色丁香婷婷综合| 99热这里只| 五月丁香综合网色欲| 97在线视频 欧美| 婷婷五月天激情网| 丁香五月色| 激情综合五月婷婷| 精品人妻久久久久| 国产精品视频久久99| 婷婷丁香五月亚洲欧美| 在线成人网址| 色九月婷婷丁香| 草草色情综合网| 婷婷亚洲天堂| 五月丁香六月婷婷网| 夜夜骑夜夜撸| www.亭亭五月天| 色色色视频免费无码 | 日日噜噜夜夜狠狠久久丁香六月| 超碰在线综合| 天天日夜夜爽| 99热这里只有精品5| 色婷婷狠狠色| 精品九九视频| 久香草视频在线观看| 99re99在线看| 久久婷婷五月| 九九热a| 182TV亚洲| 丁香五月激情欧美| 男人天堂AV在线一区二区| 99热热热99精品婷婷| 夜夜干天天操| 激情綜合W W W,激情五月天| 欧美久热| 久久久久这里只有精品| 人人爱操| 麻豆AV一区二区三区| 久热免费视频| 欧美精品XXXXBBBB| 九九日伊人| 99精品网| 99热免| 丁香五月天啪啪| 六月婷欧美| 久久五月天激情婷婷| 国内自拍1区| 久久精品一区二区三区四区| 99久久精品免费精品国产_国产精品久久久久久_国产在线|日韩_久久国产精品电影 | 涩综合在线| 精品五月视频婷婷在线观看| 久久这里这里有精品免费视频| 伊人久久艹| 亚洲综合婷婷五月| 噜噜色天天开心| 成人丁香五月| 狠狠色情婷婷| 婷婷瑟瑟五月天| 综合五月网| 久久五月天色| 日韩在线视频网站| 日本色色网| 亚州美女| 亚洲天堂玖玖| 日韩在线视频中文字幕| 中文久久久人妻| 色婷婷在线综合色播网| 欧美人人草| 五月激情影视| 99精彩视频| 亚洲妇女熟BBW| 中文字幕视频色婷婷| 好吊兆人妻| 五月丁香日逼| 五月天激情图片| 天堂AV三级| xx综合网| 色婷久久| 最近韩国日本免费高清观看| 色色色五月| 天天综合久久| 欧美激情xxxXX| 99久久精品网| 五月天婷婷基地综合网| 97色吧| 精品五月花| 东京热免费视频网站| 久久婷婷热| 狠狠干在线视频| 日日插日日干| 天天综合在线网| 熟女人妻视频| 亚洲六月色婷婷| 小视频在线亚洲| 亚洲99精品欧美一区| 亚洲A色| 午夜大香蕉| 思思 热 99| 99er精品视频| 99热首页| 久久五月六月| 最新日本A片| mmm1717.6dbm人人爱人人操| 激情综合色| 日本色色网站| 中文字幕有多少字| 婷婷六月色开| 骚。com| 99爱爱| 久久婷婷艹| 亚洲中文av| 色综合综合色| 亭亭玉月丁香| 五月开心久久| 久久aaaa片一区二区| 99热综合网| 亚洲中文字幕AV在线| 综合久久五月天| 99色播| 亭亭色色五月天| 婷婷在线五月综合| 另类图片五月天婷婷| 久久99精品久久只有精品| 激情四射五月天| 婷婷99狠狠躁| 激情久久伊人| 六月丁香成人| 91精品久久久久| 天天久久婷婷| 综合网激情五月天| 开心五月婷婷| 婷婷综合色色| 狼人婷婷久久| 六月综合婷婷开心伊人| 九一99| 操91| 五月丁香色婷婷婷基地| 久99热| 色99无码| 思思热精品在线视频| 欧美激情综合五月色丁香| 色婷婷电影| 五月激情天| 极品精品一区二区三区在线| 五月丁香六月婷婷中文版| 91一起操| 亚洲人妻av| 色综合丁香婷婷| 影院久久久| 激情五月天色爱| 激情婷婷丁香| 99亚色色色| 婷婷中文无码| 青青草轻轻操| 综合久久97| 无码动漫av| rr天天操| 人人操人人看97干| 天天干天天爽| 色五月婷婷操逼| 日本天天色| 婷婷丁香婷婷97| 婷婷丁香综合成人| 香蕉五月婷婷| 深爱婷婷网| 五月网网站| 午夜69成人做爰视频| 小视频在线亚洲| 日本天天色| 欧美操人| 91操人视频| 日韩色色色99| 超pen个人视频97| 婷婷狠狠久久| 夜色五月天| 五月成人网天天| 婷婷久久色五月婷婷久久久| 激情欧美五月丁香| 五月天丁香综合久久国产| 五月婷婷激情日本| 亚洲永久四色| 女人高潮内射99精品| 天天做天天爱天天爽在| 亚洲正能量欧美| 丁香五月区| 欧美六月婷婷| 91色五月| 欧美婷婷五月激情| 五月丁香激情综合网官网| 日日日天天干| 亚洲操逼片| 六月丁香激情网| 婷婷五月丁香影院| 东北熟女视频99| 激情五月六月| 五月天无码| 婷婷五月花| 国产成人va在线| 东京热人妻一区二区三区在线| 开心激情五月天网| 婷婷丁香五月亚洲欧美| 综合天堂AV久久久久久久| 草做免费在线观看| 综合狠狠干| 国产这里只有精品| 这里只有精品69| 九九99热| 国产FREESEXVIDEOS性中国| 伊人狠狠操| 丁香五月黄色| 天天做天天爱天天爽| 26uuu欧美亚洲日韩| 99在线综合视频| 99ri精品视频在线观看| 婷婷玉月丁香五月在线视频| 久久婷婷东京热| 九九99久久| 日本不卡五月婷婷丁香| 爱操人妻| 超碰2021| 在线只有精品| 欧美婷婷成人| 激情五月综合六月丁香婷婷狠狠干| 久久这里只有精品视频15 | 人妻久久久久久久久妻久久久久| 婷婷趴趴| 无码视频国内精品久久久| 五月丁香五月婷婷| www婷婷色情网| 偷偷操99| 日操夜操天天操不卡| 丁香九月婷| 久热这里只有精品66| 97影院一级片| 色五月激情综合网站| 激情五月丁香五月| 色五月AV| 草婷婷在线| 色欲天天综合| 激情婷婷视频在线| 一本大道伊人AV久久综合| 五月丁香婷婷综合久久| 国产五月天欧美色| 色五月天成人在线| 色99在线| 91九色国产熟女| 操B视频在线播放| 色99在线| 久9免费视频| 激情婷婷六月| 十月丁香婷婷| 九九精品网站| 色婷婷五月天成人网| 热日韩欧美| 婷婷丁香六月| 丁香五月影院| 五月天婷婷操逼视频| 日本AAAAAAAAAAAAAA片| 伊人国产婷婷五月天| 综合大香蕉| 婷色视频| 激情五月婷婷她| 91妻人人爽人人看片| 亚洲热视频在线| 97五月天| 九九成人视频| 五月天网站免费欧美| 青青草婷婷综合五月| 天天想夜夜爽天天爽| 日韩成人AV在线播放| 天天色综合综合| 天天激情综合| 欧美欧盟性爱网| 亚洲最大在线| 日韩99视频| 色五月婷婷激情基地| 久9综合| 天天操天天插| 最近中文字幕大全免费版在线| 色婷五月| 丁香五月成人社区| 狠狠色狠狠操| 五月婷婷综合网| 色婷婷电影| 九色PORNY自拍成人精彩视频| 日本色视| 久久亚洲无码| 99在线播放视频| 婷婷激情在线| 九九碰九九爱97超碰| 午夜亚洲国产精品av一区二区| 99热色精品| 可以免费观看的AV| 二色AV| 91 九色 熟女| 色五月婷婷五月天| 中字幕视频在线永久在线观看免费 | 男人天堂亚洲综合| 五月丁香久久综合精品| 五月丁香人人婷婷在线观看| 狠狠色 综合色区| 99热这里只有精品 搜| 五月婷婷开心丁香| 99精品热| 九九九热精品| www99热| 免费视频WWW在线观看网站| 99精品偷自拍| 奇米色大香蕉| WWW.99视频| 激情网第九色| www.日韩艹| 五月丁香龟婷婷| A久久| 亚洲中文字幕AV| 色婷婷av在线观看| 国产女18毛片多18精品| 97日在线视频| 免费国产VA国产免费| 呦呦v线| 五月婷婷天| 久久丁香五月| 激情婷婷五月天| 91a片爽| 综合色网站| 婷婷亚洲天堂| 天天色官网| 色色99| 五月天综合| 婷婷色色综合| www.jiujiujiu| 青草性爱视频| 色婷婷视频在线| 日韩欧美一级大黄网站| 97日韩无套内| www..999热久| 俺也去综合| 天天天天操| 狠狠干综合| 99热99日天天干| av久热| 色色色色色色97| 久久久久网站| 久久精品A片777777| 一起草aV| 色婷婷丁香五月在线| 激情五月婷婷五月丁香五月开心五月| 五月色亚洲| 色亭亭九月| 亚洲色久| 人妻内射视频| 亚洲无AV在线中文字幕| 国产老熟妇亲子乱对白| 2w在线视频| 六月丁香久久| 免费看片在线观看| 婷婷黄色五月天在线视频| 丁香五月婷婷AV在线| 色九月婷婷| 六月丁香狠狠爱| 综合热无码| 九九AV在线| 无码字幕中文| 99久久99热| www.色婷婷.com| 91久久久久久久久久18| 五月色综合网欧美网| 天天日,天天插| 欧美激情综合色综合啪啪五月| 2015WWW永久免费观看播放| 丁香激情合作五月| www.夜夜操.com| 人人插9| 亚洲色综合性| 精品夜夜澡人妻无码AV| 91啪啪视频| 中文字幕 中文字幕明步| 99噜噜噜在线播放| 成人天天爽| 99热最新精品| 久久天堂加勒比| 久久人妻高清中文| 亚洲视频在线观看| 五月丁香婷婷综合在线| 久久色婷婷| 综合网啪| 色99在线观看| www.九月婷婷丁香.com| 国内精品玖玖| http://www.com久久久精品一区| 婷婷五月成年人| 成片免费观看视频大全| 9久国产| 免费观看的婷婷五月视频在线| 超碰97在线操| 少妇久久诱惑视频| 香蕉AV777XXX色综合一区| 婷婷五月中文在线| 99热97| 99热自拍| 色色五月婷| 伊人激情综合网| 激情综合网激情五月天| 99ri精品在线| 五月丁香色色| 99热99色| 久久九九色| 九九热这里只有精品5| 婷婷五月天久久| 亚洲五月天婷婷综合| 777色色色| 婷婷五月天综合网| 亚洲妇女熟BBW| 丁香五月婷婷av| 久久久人妻| 狠狠色大香蕉| 日本色天堂| 热久国产| 色色免费网站| 欧美激情丁香五月天久久婷婷一区| 9热久久| 激情五月天激情五月天| 色色色网站| 丁香五月婷综合| 天堂久久精品| 丁香九月婷| 色色性爱视频| 五月天激情在线视频| 少妇人妻人伦A片| 蜜桃五月天色| 丁香久久九九99| 五月天天天天天天天天天天天天天天天婷婷婷| 五月丁香综合成人社区| 综合网色| 丁香五月天婷婷久久综合| 天久综合91综合首页| 天天爱天天日| 色色色热| 九九热这里只有精品31| 日韩 mm 不卡| 色婷婷大香蕉| 日本婷婷网| 91久久国产自产拍夜夜91久久精品文字>91麻豆精品国产 | 狠狠色噜噜狠狠亚洲A∨| www.婷婷五月天| 成人短视频在线观看| 丁香五月天激情网址| 电影91久久久| 五月婷深深爱激情网| av在线免费播放观看| 丁香色五月天| 天天干天天干天天干| 国产毛片精品一区二区色欲黄A片| www。久久久久一b。Cc| 99操网站| 大香蕉婷婷丁香| 欧美在线干| 蜜臀av无码久久久久久久久| 日批在线看| 五月婷视屏在线观看| 亚洲人人操| 色吧综合网| 少妇高潮呻吟A片免费看软件| 超碰婷婷色| 中文字幕+中文在线| 97色欧美| 99热国内| 狠色色狠网| 激情綜合網址| 超碰人妻在线| 99碰碰碰| 殴美日比视频| 丁香五月天婷婷久久综合| 久 久9 9 热 视 频| 国产激情在线| 国产美女无遮挡裸体毛片A片| 懂色av粉嫩AV蜜臀AV| 色情五月婷| 亚洲中文无码成人| 99色性爰网络| 婷婷色六月| 亚洲综合视频八| 超碰在线视屏| xfplayav在线| 日韩久热| 五月天激情美女久久| www.久久9| 久久五月丁香伊人青草| 综合五月婷婷| 欧洲MV日韩MV国产| se99视频| se99视频| www.9色色色| 国产精品久久久久久白浆色欲| 青青草护士中出内射-欧美电影在线天堂新版 | 日本熟妇精品99| 五月激情婷婷播播网| 丁香五月AV| 亚洲情综合五月天| 182TV亚洲| 天天日天天操天天干| 五月丁香无码| 婷婷碰碰| 久久草人妻| 五月天啪啪啪| 国产美女无遮挡裸体毛片A片| www.久久爱.c n| 六月丁香深深爱| 97色永久免费视频| www日本熟妇99在线视频| 538任你爽| 人人爽欧美婷婷久久久五月丁香| 开心五月婷婷| 铁牛TV人妻| 天天狠狠色综合| 久久99热这里只有精品| 亚洲无码激情| 六月色色婷婷| www.夜夜操| www.91在线看| 蜜桃五月天色| 五月婷婷激情网| 99ri在线播放| 丁香五月综合在线观看| 五月丁香啪啪啪| 99日本在线| 99久在线精品99re8| 中字幕视频在线永久在线观看免费| A片一曲| 色五月人妻| 婷婷5月久久综合网站| 噜噜色五月| 六月丁香啪啪啪| 人妻操日日| 操婷婷基地| 激情五月天色爱| 五月天色社区| 99婷五月| 黄色av网站在线免费播放| 婷婷激情六月综合| 99这里有精品视频| 91九色 熟| 久久狠狠色| 婷婷色婷婷| 五月丁香另类图片| 欧美日韩国产一区二区| 婷婷色婷婷| 五月天色婷婷小说| 六月婷婷中文字幕| 色噜噜狠狠色综合成人网| 夜夜骑夜夜撸| 97色综合| 久久这里有精品在线观看| 色五月激情五月| 激情综合女人网五月播播| 超碰碰碰碰| 成年人看Va免费视频| 97人人操| 色99在线看| 天天天天干| 婷婷五月成人社区| 玖玖午夜视频| 九九热10| 丁香六月婷婷综合欧美| 九九热视频精品999| 69激情小说| 中文字幕有多少字| 国熟女视频| 国产精品天天狠天天看| 日本色婷婷久久99精品91| 在线播放中文字幕| 艳妇野外情欲放荡HD| va中文资源在线观看| 国产激情久久| 99热这是里只有精品| 亚洲狠9| 我爱大香蕉| 99ER热精品视频| 亚洲另类视频| 丁香五月综合高清在线| 91麻豆国产三级精品福利在线观看| 月婷婷婷婷五月| 激情五月天久久丁香| 久久五月天影院| 色综合久久88色综合天天99| 深爱五月天婷综合| 色婷婷综合影院| 日本综合色图| 色色色色色网| 婷婷综合五月激情| 五月天婷综合| 亚洲AV在线免费看| 色综合久久天天综合网| 五月天四色房丁香| 亚洲 视频 导航 一区| 9+1视频网址| 日本美女五月天| 婷婷五月天国产手机在线视频观看| 久久久久久久久久久jjjj| 综合网色| 亚洲情a| 色就是色婷婷五月亚洲激情| 丁香色色五月| 五月丁香六月婷| 激情丁香五月天| 深爱激情四射| 亚洲视频五区| 91精选国| 无码激情AAAAA片-区区| 婷婷操超碰| 激情五月四色| 激情五婷精品网在线观看网址| 婷婷五月丁香激情图片| 人妻熟人中文字幕一区二区| 在线观看欧美| 五月天激情网开心网| 婷婷丁香五月av| 国产精品美女| 玖玖婷婷五月天毛片| 在线不卡视频| 99爱在线视频观看| 小视频aaa久久久| 97综合在线| 七月激情六月婷婷综合在线播放| 狠狠干最新地址| 六月激情婷婷| 国产成人在线不卡AV| 日韩操逼大片| 狠狠干,狠狠操| 性天天中文网| 很很干五月天| 97深爱伊人综合| 色噜噜狠狠色综| 久久婷婷五月综合色奶水99啪| 天天日日| 97碰碰草| 人人摸人人干| 99热热热99精品婷婷| 九九激情网| 婷婷六月丁香五月| 99热在线精品观看| 外国碰视频网站97| 欧美色色色色色色| 99精品免费视频| 人人操人人爱丁香五月| site:ornaments52.com| 色综合天天网| 97涩涩丁香五月天| 亚洲综合在线视频| 玖玖视频福利| 538在线| 99综合色色色| 翔田千里aV中文字幕| 9er热在线精品视频| 久久狠狠欧美| 五月婷婷高清| 99在线观看视频精品| www,8050,午夜三级| 99re66热这里只有精品| 天天日综合网射| 丁香五月中文字幕| 好好干Av| 狠狠色情婷婷| 五月天激情婷婷五月天久久| 狠狠狠狠操| 天天做天天爱综合| 婷婷久久色| 99免费热视频在线| 97干97色| 九九这里只有精品| 欧美在线| 婷婷丁香五月社区亚洲| 99热99| 96精品久久久久久久久| 婷婷久久99| 亚洲操逼网| 亚洲乱码日产精品BD| 性做爰1一7伦| 激情五月天福利| 亚洲传媒在线观看| 久婷视频| 婷婷永久在线| 99热99热在线观看| 俺去啦综合网| 亚洲激情免费视频观看| 午夜婷婷久久 | 色综合色综合色综合| 色五月色五天免费视频| 另类图片五月天| 五月天婷婷社区| 最新高清无码专区| 久久婷婷五月综合一| 99ri精品| 丁香五月天婷婷久久| 婷婷五月天激情电影小说| 91婷婷色五月| 少妇水多A片太爽了| 色天堂97| 激情五月深爱五月| 色导航色婷婷五月天在线观看| 天天噜| 欧美成人精品A片免费一区99| 伊人久热91| 五月大香蕉| 久久A区B区| 日韩久久色| 91se精品国产| 99ri在线观看视频| 人人射av| 99热都是精品| 久久综合五月天激情小说网站| 爽极品色| 日日操天天| 殴美激情综合网| 婷婷五月天深爱| 涩综合婷婷| 日韩一区二区A片免费观看| 99碰网站| 美国天天日天天操| 五月婷婷色| 99热狠狠操| 日日爽日日操| 婷婷激情五月综合| 狠狠爱丁香婷| 丁香六月av| 丁香激情网| 丁香婷婷浪潮AV久久综合| 97色色色色色色色| 日日操夜夜爽| 亚洲AV日韩在线观看| 日日日日做夜夜夜夜无码| 婷婷五月丁香综合激情| 国产美女无遮挡裸体毛片A片| 97影院一级片| 天天做 天天爱| 丁香啪啪| 国产成人在线精品| 妻久久人久久| 黄色片avv| 熟女婷婷网站一婷婷五月一丁香婷婷一婷婷激情网 | 亚洲天堂久久| 深爱激情丁香| 麻豆忘忧草午夜| www.色婷婷。com| 国产超碰在线| 综合久久97| 激情五月天激情五月天| 99碰碰。| 九热视频这里只有精品| 久久婷婷六月综合综合| 99热在线中文字幕| 婷婷五月综合啪| 色欲久久99精品久久久久久| 亚洲五月婷天天操| 色色热| 99成人网一区| 九九热在线99| 五月天丁香成人| 五月天天综合| enecarbon-materials.comWu染请涟系Bao护@wip1688 | 日本五月天网站| 影音先锋五月婷婷| 五月天夜夜爱夜夜操| ..真实国产乱子伦对白在线_欧| 99久热| 九九热在线精品视频| 精品乱码视频| www.久久久久久久| 久久人操| 亚洲婷婷五月天| 四月婷婷五月色综合| 深爱激情五月婷婷| 婷婷五月天堂| 丁香婷婷基地| 99热香港| 天天插天天日| 伦乱美欧| 人妻体体内射精一区二区| 久久婷婷激情五月天一区二区| 99色天堂| 小视频一区| 婷婷五月天电影网| www色婷婷久久综合久色 | 99综合视频一体| 激情婷婷内射| 国产乱妇无乱码大黄AA片| 偷拍91九色| 79精品视频在线观看,| 五月丁香美女视频| 久久婷婷热| 国际国外精品欧洲南美洲专区无码不卡| 国产精品A成V人在线播放| 26uuuavcom| 极品嫩草| 五月丁香婷婷深深爱| 日韩另类在线观看| 五月婷婷啪啪| 九月婷婷综合八月丁香在线观看| 熟女人妻一区二区三区免费看| 五月婷婷丁香色吧网| 狠狠色丁香久久综合婷婷亚洲成人福利 | 日本本土色网第一区| 人妻丰满精品一区二区A片| 五月婷婷无码专区| 狠狠狠狠狠狠草| 91凹凸在线| 玖玖在线视频福利| 五月天丁香| 五月天婷婷爱| 强壮公让我夜夜高潮A片视频| 日韩精品无码99| 五月丁香啪啪综合| 国产精品蜜臀99| 日本人妻伦在线中文字幕| 77799热| 一级黄色影片| 色爱99| 开心激情站| 99久在线| 狠狠狠狠狠| 色五月首页| 久热99热| 少妇高潮呻吟A片免费看软件 | 超碰2021| 狠狠干狠狠色| 久色欧美| 九九九日本熟女| 亚洲黄网在线| 狠狠色成人影片| 色综合久久综合| 极品少妇XXXX精品少妇偷拍| 九色啦蜜臀| 亚洲激情免费久久| 久热久re| 亚洲亚洲人成综合网络| 色婷婷电影网| 热久久思思热思思| 大香蕉九九热| 色色色综合网| 99精品福利视频| 91免费在线视频6| 亚洲中文AV| 五月天成人小说| 色婷婷五月天偷拍| 色色色.com| AV在线中文| 色天使久久综合| 色婷视频| 超碰在线超碰| 思思热99在线| 激情婷婷色小说| 国产资源在线视频| 91.www综合| www.狠狠| 色五月激情五月开心五月| 色情激情五月| 亚洲sesesese| 激情五月婷婷啪啪| 亚洲mm免费| 亚洲激情四射| 激情丁香五月婷婷啪啪| 色五月婷婷天天干| 久久婷婷五月天激情四射| 97超碰99热99| 99精品视频在线观看| 91一起操| www.91九色| 欧洲亚洲精品| 五月天色婷婷网| 激情五月丁香色婷婷| 国产成人av在线| 五月婷婷丁香大陆免费| 91操在线观看| 狠狠婷婷日韩| 99热综合在线观看| 丁香婷婷五月份| 色情综合网| 99re思思久久| 深爱激情五月婷婷| 色5月婷婷| 久热黄色| 天天色图| 99色色网| 婷婷色网站| 久久综合中文| 三级三久久线久久99久目本WW| 色99日韩| 五月丁香六月激情综合| 综合激情在线| 91男同| 99热热这里只精品996小说| 五月天婷综合| 九九综合伊人| 91人人操人人爱| 殴美综合激情五月天免费视频| 久久婷婷视频| 99男人的天堂| 日韩在线婷婷五月天综合| 曰日爽日日操| 26uuu日韩| 丁香五月伊人| 99爱精品| 大香蕉520| a久久| 六月丁香网| 黑人巨粗进入警花疼哭A片| 草草色情综合网| 激情五月天激情综合网| 少妇久久诱惑视频| 6月丁香婷婷| 色很很96| 精品人妻伦| 岛国av电影网站| www,婷婷| 性色婷婷| 91日韩在线| 搡BBBB搡BBB搡五十| 免费超碰在线观看| 五月天另类视频| 极品人妻VIDEOSSS人妻| 久热A片| 九九人人精品| 色情综合| 亚洲色欲AAAAAA| 婷婷久久亚洲| 久久久久激情| 97在线精品| 伊人丁香在线| 99九九视频| 99er这里只有精品| www.五月天婷婷姐姐| 色亚洲欧洲| 久久久性爱视频| 日B日潘金莲BB| 天天射色五月天| 国产91视频| 99精品网站| 色婷婷亚洲婷婷| 五月天桃色深爱网| 亚洲成人网址在线观看| 91成人视频| 日韩无码人妻一区二区三区综合 | 天天干天天操天天爱| 九九99九九99偷拍视频免费看| 九九热精品视频| 色婷婷色丁香色欲av| 综合网色| 亚洲另类噜噜| 婷婷色影院| 婷婷九九色| 永久思思热在线| 五月综合婷婷五月| 激情www| 91精品久| 九九这里只这里只有精品| 一区二区三区四区无码| 国产毛片欧美毛片久久久| 超碰97在线观看免费| 久草五月婷婷| 日韩成人电影在线播放| 热久久国产视频| 狠狠色五月| 2018夜夜草| 五月综合丁香婷婷| 色婷婷在线视频综合| 国产操碰| 91人无码久久久久久| 99久久久国产大片| 成人在线视频一区| 白人荫道BBWBBB大荫道| 久久色天堂| 婷婷五月色综合| a在线观看| 五月丁香亭亭激情操逼网| 色色热99| 五日激情综合| 婷婷亚洲在线| 色亚洲视频| 色婷婷9| 五月婷婷电影院| 天天在线天天综合网色| 久热欧美| 影音先锋综合网| 五月天a婷婷伊人| 五月丁香综合激情| 玖玖色综合网| 情趣视频66| 久久99久久99精品,久国产,久久精品免费,99久在线,久久久久国产精品免费网站,9 | 2005天天干天天1| 欧美丁香六月在线观看视频| 九热视频在线精品15| 婷婷五月天丁香久久| 国产一级婬片毛片| 激情五月综合网| 另类A片| 天天干天天叉| 99久热| 婷婷激情在线| 六月丁香AV| 激情五月色综合国产精品| 岛国AV网站| 青青久久五月| 九九热这里精品| 伊人色综合网| 爆乳熟妇一区二区三区爆乳| 婷婷五月色播| 欧美伊人9| 久久综合激情婷婷激情| 国产真人做爰视频免费| 国产成人VA| 夜夜爽77777妓女免费下载| 五月天激情四射| 五月婷av| 日本 欧美在线| 久久9视频| 手机在线日韩视频中文字幕| 9月色婷婷| 综合色色综合| 人妻激情综合| 欧洲精品爱爱| 色婷久九|