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片蜜桃| 99久久97久久欧美综合网| 99亚洲精品视频| 国产精品人妻在线网址| 婷婷五月天色色| 久久A热| 日逼影音先锋男人资源站| 人妻VideOssS人妻高清| 成人电影一区| 久久99精品久久久| 天天射影院| 丁香五月在线播放| 国精产品一区二区三区| 一级无码作爱片| 日本九九视频| 六月久久狠狠| 丁香六月天之亚州热女| 国产欧美日韩综合精品一区二区| www999日韩精品| 日本三级大片| 大香蕉中文| 九九成人视频| 大香蕉伊人99| 日本成人噜噜噜| 99色6爱9热| 任你干aa| 婷婷色色网站| 色狠狠色噜噜AV天堂五区| 九九热在线视频| 五月天亚洲最大成人| 99久免费视频| 91丨九色丨熟女丰满| 亚洲正能量欧美| 97福利视频| 天天操电影院色狼性av| 激情校园 亚洲| 亚洲蜜乳AV| 亚洲色无码A片一区二区麻豆| a网站免费观看| 中文在线视频久1| 91丨九色丨熟女高潮| 99欧美三级视频| 国内精品99| 超碰在线人妻| 大香蕉五月婷婷| 91狠狠色丁香| 婷婷久久综合久| 亚洲乱码在线观看| 激情六月婷婷| 久色激情| www...com黄在线观看| 国产XXXX搡XXXXX搡麻豆| 狠狠爱综合| 思思热高清在线观看| 激情五月天噢美| www.99精品视频| 欧美色色色色色色| 五月丁香激情综合啪| 日韩av在线电影| 色情激情五月婷婷| www狠狠爱com| 97色婷婷在线观看| 琪琪理论片| 91久久久久久久| 丁香五月情色| 日本ww亚洲| 人人人操B超碰| 色播五月天激情| 五月丁香影院| WWW.桔色成人.COM| 九九热内射| 色色色五月| 狠狠干最新地址| 伊人激情网| 色婷婷色综合激情91| 婷婷丁香大香蕉| 色综合久久之分久久| 中文成人在线| 4438国产免费看| 2017狠狠干| 日本视频欧美观看免费| 91蜜桃婷婷狠狠久久综合9色| 玖玖99福利| 婷婷六月丁香在线| 六月丁香啪啪啪| 思思热视频在线| 色丁香五月婷婷| 最近中文字幕2019视频1| 五月天婷婷激情六月久久| 婷婷黄色五月| 热久久视频99| 综合网啪啪| 久久久精品人妻| 大香蕉在九| www.亚洲激情.com| 五月色丁香综合| 国产精品日韩十五区| 五月丁香综合激情网| 国产精品色色| www.久99| 思思热99er在线视频| 五月丁香色婷婷基地| 欧美色色色色色色色| 97色天堂| 色yeye欧美| 91丁香| 人妻内射麻豆视频| 激情五月婷婷五月| 超碰在线人妻| www.五月天色色.com| 亚洲精品一区中文字幕乱码| 成人片久久网站| 激情第四色| www,奇米影视| 俺五月| 六月天婷婷| 成人国产欧美大片一区| 色五月婷婷 成人| 色五月,婷婷大香蕉| 久草大| 久月丁香爱婷婷综合| 六月份天丁香婷婷| 超碰伊人碰婷婷五月| 成人 在线 日韩| www.minyis.com【JT】币址百万U预算可预付QQ2101460746 | 亚洲色综合| 伊人综合色干| 婷婷五月色天| 天天躁日日躁狠狠躁日日躁2022年5月9日| 日本一级特黄大片AAAAA级| 综合亚洲色色| 9热视频在线观看| 丁香五月婷婷激情中文| 婷婷十月激情综合网| 色婷久久| 色一情一乱一乱一区91Av| www.九九婷婷| 欧美xx激情视频在线观看| 色婷婷小说| 美女91一起草| 婷婷五月天亚洲综合| 99视频内射三四| 色呦呦免费观看| 五月婷综合性中心| 国产在线网址1| 国产精品久久久60086| 日韩精品AV一区二区三区| 人妻性爱av网站| 婷婷九月综合| 婷婷久久婷婷色五月| 婷婷五月天影视首页| 五月天激情日色在线| 天天操夜夜肏| 久久免费少妇高潮99精品| 婷婷久久五月天亚洲欧美国产日韩在线观看 | 91在线看片| 91婷婷伊人牛牛| 久色视频| 色婷婷手机在线| 五月丁香| 99热这里只有精品50| 日日影院 | 五月天色婷婷图片| 人人操五月天| 五月综合影院| 7超碰自拍| 亚洲AV中文在线| 亚洲成人av在线| 激情五月天com| 91疯狂操操操操| 婷婷伊人综合中文字幕| 天天拍夜夜爽日日| 天天综合久久| 99精品在线观看| 国产亚洲99久久精品| 男女99免费视频| 日韩三级片一区二区| 午夜天堂一区人妻| 五月天婷婷操逼视频| 久久ri精品视频| 五月天狠狠| 久久综合丁香| 日本A片一区| 婷婷激情综合| 五月色丁香综合| 久久99久久99精品,久国产,久久精品免费,99久在线,久久久久国产精品免费网站,9 | 第四色婷婷色五月| 日本高清久| 任你爽视频| 激情九九这里只有精品| 久久婷婷五月| 久操人| 色丁香五月| 久久99热精品a片在线观看| 在线日韩av| 久久99综合| 成人视频网| 六月婷婷在线| 丁香婷婷人妻综合网| 成人无码中文| 婷婷香草网| 婷婷综合一二三| 久久日韩婷婷五月| 亚洲精品国产熟女久久久| 色色网站| 婷婷五月天手机版视频| 丁香午月AV中文字幕| 丁香操逼| 日韩成人精品中文字幕电影| 夜夜骑夜夜操| 五月婷婷网站| 91九色精品熟女内射| 亚洲深喉aV| 丁香五月激情综合| 五月婷婷香| AV天堂淫乩| 五月天另类小说久久小说网| 亚洲人妻av伦理| 国产另类综合| 九九免费在线视频| 婷婷丁香五另类网站| 91色在线 | 日韩| 五月天激情小说| 五月丁香婷草| 97色色视频| 婷婷五月天第四色| 久久人人人人妻| 婷婷色五月激情| 久久婷婷91| 97在线视频 欧美| 国外亚洲成AV人片在线观看 | 伊人99久久| 五月丁香综合| 激情五月激情综合网| 亚洲AV成人片无码网站| 中文字幕,综合,91| 婷婷婷久久| A片试看50分钟做受视频| 成人在线视频网| 久久9热| 久久机热这里只有 | 中文字幕在线免费观看视频| 日韩人妻在线观看| 91精品婷婷国产综合久久| 五月亭亭色| 亚洲日比视频| 欧美熟妇一区二区三区| 永久免费一区二区三区| 九九99免费理论| 艹天天射| 色婷婷免费观看| 超碰狠狠干99| 久久密臀婷婷| 99久操视频| 99精品视频免费观看| 日韩一区二区三区无码| 级情九色| 琪琪理论片| 色色综合成人网| 人妻AV在线| 亚洲五月天,激情视频| 成人在线日韩| 日日色五月天| 激情五月天伊人av| 丁香花五月天激情| 亚洲色图五月丁香| 精品久久99码| 久热最新视频| 俺去也五月天| 亚洲操B| 色99视频| 国产婷婷久久| 日韩色色网| 色婷婷成人在线| 深爱激情九九五月天| 狠狠操.COM| 五月天综合在线观看| 99激情视频| 五月天丁香成人社| 激情五月婷婷| 激情综合在线观看| 婷婷六月久久| 婷婷五月综合社区| 91性交在线播放| 欧美97超碰| 9视频1在线| 天天射综合网站| 五月天激情网图片 - 百度| 婷婷五月深深爱| 婷婷五月色| 人妻av在线| BBWCUCKOLD精品熟妇| 色都都狠狠色都都色综合色| 天天做天天爱高潮片| 狠狠色五月| 亚洲小电影在线观看黄999| 97人妻碰碰碰久| 啪啪啪五月天| 综合色五月| 亚洲偷| 中文字幕av在线播放| 久久婷婷丁香五月一二三| 日韩十国产极品久久| 色婷婷免费视频| 偷偷与邻居做爰完整视频| 39视频第二区| 五月婷婷六月婷| 欧美在线干| 久久涩视频| av国产精品偷| 久久ab| 五月激情天| 丁香视频| 丁香六月色婷婷| 色色婷婷丁香| 久久综合五月天| 九九久热| 婷婷丁香色女人| 色婷婷六月天| 99ri精品视频在线观看| 婷婷爱五月| 成人午夜天| 99在线视频资源| 色五月色五天色情网| 综合五月婷婷| 九九综合色| 99免费视频网| 九九爱激情| 97色一二三| 欧美大奶熟女噜噜噜噜| 国产67194| 1024久婷| 亚洲婷婷激情五月天| 亚洲日韩一页精品发布| 99亚洲综合| 五月丁香人妻| 入口五月婷婷六月香| 97操碰在线视频| 无码AV大香线蕉伊人| 久久黄色免费视频| 九九成人| 99热这里只有精品33| 五月天婷婷基地| 九九九九国产| www99热| 大香蕉视频婷| 丁香五月区| 操大屄五月天视频| 无码任你操| www久久久久久久久久久久久久久久久| 五月婷婷丁香深深爱| 九九综合伊人| 激情五月综合久久| 亚洲乱码在线观看| 色墦五月丁香| 亚洲婷婷五月天| 婷婷五月成年人| 久热99| 综合激情网五月激情| 五月花激情| 激情影院内射| 色九四色| 婷婷99狠狠| 婷婷久久五月天丁香| 97色97干| 国产99热在线看| 五月开心网| 午夜九九电影| 丁香五月天婷婷91| 色五月婷婷丁香五月| 人人玩人人橾| 超碰2021| 日本色色色| 色播播婷婷| 色色色com| 97婷婷五月丁香| 五月天激情久久| 亚州操操| 久久AAAA片一区二区| 操你av| 丁香婷婷六月| 91碰碰| 开心深爱五月天| 久久综合久色欧美综合狠狠| 国产精品久久久海的味道| 五月天天综合| 色狠狠色噜噜AV天堂五区| 久久九精品| www.99热精品99.com| 久9久9久9久9久9久9| 99热这里在线精品| 丁香熟女乱| 九九99免费视频| 婷婷大美在线| 97人人做| 99视频在线9| 五月亭亭开心网| 久久婷婷六月| 操碰久| 五月丁香网站| 天天爱天天操| 婷婷五月开心中文字幕在线| av久热| 欧美色片中文字幕久久久久| 99综合在线| 色五月视频无码播放| 99在线视频免费| 日韩婷婷| 日韩精品一区二区亚洲AV观看| 天天爽天天爽天天爽天天爽天天爽| 大香蕉五月婷婷丁香| 伊人久久大香线蕉av最新| 亚洲精品操一操、噜一噜、摸一摸、爽 | 99在线视频免费| 丁香五月影院| 色欲婷婷五月天| 中文字幕性爱丰满| 久久与婷婷| 六月婷婷色色色| AA片在线观看视频在线播放| 大香蕉婷婷五月天| 激情五月婷婷色| 五月天激情综合在线| 色色色色色五月| 欧美槡BBBB槡BBB少妇| 久草狼人| 五月综合激情视频在线| 天天天日天天天干| 蜜乳.comcom| 国产免费AV网站| 久久久九九九 99| 成人做爰高潮A片免费视频| 激情综合99| 丁香色综合| 婷婷黄色五月天在线视频| www.婷婷五月天| 一区二区三区四区牛| 欧美经典片免费观看大全| 婷婷五月天激情小说| 九九精品网| 天天爽综合| 五月情丁香色| 五月天色狠狠| 丁香五月婷婷婷婷欧美综合| 色色日韩网| 九九热自拍| 97超级碰碰碰| 天天肏高清在线| 婷婷久久色| 91丨九色丨国产| 婷婷五月花| 色色色99| 色婷婷丁香A片区毛片区女人区| 色婷婷丁香| 婷婷人人操| 丁香五月色网| 久久精典| 亚洲成人五月天| 久久亚洲婷婷| 日本三级日本三级99| 欧美日朝成人| 六月丁香婷| 色婷婷丁香五月| 精品色色| 激情婷婷五月丁香啪啪啪| 日本V在线观看不卡视频网站| AA片在线观看视频在线播放| 8050一级网| 99久久婷婷精品视频| 3p九色在线| 色九月综合| 亚洲色图在线视频| 久色网址| 亚洲激情五月婷婷日日| 五月天激情子轮| 黄色AAAAA| 五月的色婷婷高潮| 日本久久99| 日本va欧美va国产激情| 丁香婷婷激情网站| 丁香六月| 色五月涩涩婷婷蜜桃| 狠狠久久婷五月综合色| 久久小片| 色色色9| 99这里有精品视频| 月色色综合婷婷网| 天天情天天狠天天透| 欧美又粗又大一区二区在线观看| 久久婷婷五月天综合| 六月综合婷婷开心伊人| 中文字幕 中文字幕明步| 成人无码髙潮喷水A片| 色色色色色色综合网| 色原狠狠综合| 好好干Av| 99爱这里只有精品免费视频| 色五月在线播放| 色狠狠色噜噜AV天堂五区| 国产黄色大片| 伊人大香五月天| 丁香六月无码播放| 激情综合网五月婷婷| 丁香五月激情图片婷婷| 97干97色| 成人视频婷婷| 综合婷婷| 欧美色色色色色色色色色色| www.狠狠操.com| 欧美色婷婷| 国产精品久久久久久久久久| 夜夜躁婷婷AV| 婷婷免费无马| 五月天伊人手机在线播放AV| 少妇激情五月天| 激情五月天福利| 99热大全在线观看| 久热91精品| 日韩在线观看网址| 99色色爰| 任你操精品免费| 丁香五月婷婷综合啪啪| 色,激情五月天| 激情五月六月婷婷| 亚洲 在线 另类| 婷婷激情性爱| 欧美这里只有精品| 婷婷五月成人社区| 啪啪五月天啪啪| 99热自拍| 亚洲免费观看高清完整版AV线| 丁香五月天欧美| 亚洲色综合| www.五月婷| 天色综合网站| 玖玖爱综合网| 亚洲秘 无码一区二区三区妃光/1| 开心激情网在线| 五月天婷婷狠狠| 思思精品久久艹| 五月丁香婷婷综合网| 黄久久久| 欧美色频| 色噜久| 热成人网| 99久久婷婷综合| 色婷婷六月精品| 91丨九色丨东北熟女| 97色片| 久热99热| 激情五婷网| 婷婷五月天福利| 色五月开心久久网| 天天干夜夜谢| 艹天天射| 99狠狠| 人妻激情视频| 91丁香五月| 丁乡久久| 久久99久久99精品免视看婷| 五月激情啪啪啪| 天天综合网91| 99热精品在线观看| 99综合网| 亚洲女婷婷五月基地综合久久久| 天天碰夜夜操| 色婷婷色婷婷五月| 婷婷激情五月天小说| av狠狠操| 综合性爱网| 欧美日韩成人高清在线| 91久久久久久久久18| 97香蕉碰碰人妻国产欧美| 五月婷婷色综图片| 激情99| 五月色丁香综合| 一本色道久久88综合日韩精品| 五月激情偷拍婷婷| 五月色亭丁香| 一区二区乱码视频| 婷婷五月天成人五月天| 99热热热99精品婷婷| 婷婷成人综合五月| 欧美激情 日韩无码 婷婷 五月天| 无码任你操| 亚洲AV第二区国产精品| 五月丁香六月激情在线| 成人欧美Va| 色婷婷aV四虎| 婷婷丁香五月亚洲| 国产精品久久久60086| 色开心五月婷婷丁香HD| 92久久| 婷婷久久五月| 亚州婷婷五月激情综合| 六月激情婷婷| 思思热精品在线观看| 99久re热| 久久综合九色综合97婷婷| 欧美综合激情五月天| 婷婷五月中文字幕| 内射人妻视频国内| 亚洲综合另类| 五月婷婷这里都是精品| 美欧成人视频| 国产真人做爰视频免费| 99视频在线精品| 精品在线| www,色综合| 丁香五月av| 激情五月www| 日日干天天爽| 操骚货在线| 日本的α片xxxwww| h亚洲| 成人午夜天| 欧美乱码国产一级A片| 99er免费在线观看| www.久久久久久久| 日韩精品一曲二曲三曲四曲五曲| 亚洲五月天婷婷| 五月天婷婷在线AN| 一个色的综合| 人人操99| 婷婷五月天久久综合88| 久久精品凹凸分类| AVDV久久| 91九色中文字幕女在线观看| 这里只有精品在线看| 99在线观看| 五月丁香婷婷激情四射迷人| 久久性爱网| 天天狠狠夜夜狠狠2023| 可以看的av| 综合图区激情| 激情丁香五月激情婷婷| 操操操操操操婷婷五月天| 97婷婷丁香五月天激情图片| 色欲五月丁香| 亚洲色无码A片一区二区麻豆| 九色91视频| 五月激情偷拍| 热99热9| 五月丁香啪啪激情| 婷婷色播色五月五色五月天色妇| 97久久草草超级碰碰碰| 婷婷网影院| 日本英国美国欧美亚洲国产精亚洲日韩精品在线观看 | 九伊人网| 爱iii做iiii日日| 激情丁香五月| 五月婷婷激情| 天天日天天插| 天天插天天插| 熟妇内谢69XXXXXA片| 人妻少妇色综合| 人妻综合网| 激情婷婷丁香五月天| 国产这里只有精品| 婷婷 丁香 精品| 亚洲狠狠干| 啄木鸟丝袜美女福利视频| av在线色五月丁香婷区久| 熟女五月天久久综合| 激情五月图| 丁香五月AV在线| 激情五月天婷婷久久久久久久久久久| 99爱视频精品| 99久久亚洲精品视频| 色婷婷导航| 色综合激情| 亚洲色色色色色色色色色| 97色在线| 婷婷区日本| 2025天天爽天天摸| 26uuu欧美激情另类| 26UUU精品一区二区Com| 婷婷五月天首页| 色色网五月激情| 天天干 夜夜爽| 色色亚洲| 五月色婷婷综合| 婷婷五月天伊人| 无码激情AAAAA片-区区| 九九99九九精品视频| 色yeye色综合| 大香蕉伊人99| 六月综和久久| 婷婷五月天在线综合| 99热这里只有精品8| 色5月婷婷色| 九九色影院| se色婷婷视频| 五月香蕉婷婷| 色婷婷久久综合久色| 激情狠狠丁香月| 婷婷色五月天在线观看| 99re久久| 国产精品日本一区二区在线播放| 99精品手机在线视频| 成人资源在线| 婷婷五月黄色激情在线| 凹凸操Av| 色热久| 少妇搡BBBB搡BBB搡毛茸茸| 在线色婷婷| 大香蕉久久久| 色婷婷五月天成人网| 青青草成人网| 国产成人网| 国产a视频| 色综天天综合| 丁香综合伊人| 婷婷成年人免费视频| 开心五月激情婷婷| 五月丁香激情怕怕| 五月丁香花成人社区| 日本99在线视频| 欧美97p| www.91九色| 99色在线观看视频者| 色五月成人| 可以免费看AV网站| 色五月婷婷久久爱| 五月天丁香久久| 99热爆在线| 99爱在线免费视频| 久久怡红院| 在线A色| 操操操操操操婷婷五月天| 久久久久久18| 91色色五月天| 色情综合| 无码人妻电影| 六月婷婷色综合| 大香蕉院线| av 一区三区四区| 婷婷色五月大香蕉在线观看| 天天肏在线视频| 五月天婷婷综合| Av九九| 人人草人人爱| 色丁香五月婷婷在线| 这里只有精品99视频| 日本三级日本三级三级人妇四虎| 丁香香蕉婷婷| 丁香五月瑟瑟| 色色五月婷婷狠狠| 福利视频在线播放| 99re这里只有| 婷婷五月综合激情| 性生活视频98791| 天天干夜夜谢| 亚洲AV色婷婷人禽五月天| 甈吧vv| 日本在线免费中文com.| 99色在线观看免费| 人妻人人操| 九九AV在线| 超级碰碰91| 99九九热视频| 99色日本| 婷婷精品综合| 91超级碰在线| 欧美性爱中文字幕| 色www.con| 久热久操久热久草国产91| 日本玖玖在线| 日日操夜夜操中国无码| 婷婷婷久久| 香蕉久久五月| 91人人人人人人人| 97操男人的天堂| 九九色video| 亚洲精级| 九九热99久久99| 国产婷婷久久| 五月婷婷|欧美| 91成人看片| 色情五月天丁香社区| 婷婷五月天黄色网址| 超碰97久久| 色色色婷| 国产亚洲在线| 99热欧美在线观看| 狠狠色官网| 亚洲精| 六月婷婷九月丁香亚洲综合| 婷婷伊人五月天| 狠狠高潮精品亚洲1| 99热精品在线观看| 日韩啪啪网| 99激情| 97在线99| 九色1区视频在线| 色婷婷瘦婷婷日韩| 1024国产| 99爱免费在线观看| 久久久五月婷婷| 五月色婷婷综合| 久久 婷婷 五月天| 99热只有| 色婷婷呢狠禁久禁| 亚洲色婷婷久久99精品91| 99在线视频资源| 亭亭丁香aV| 日本九九热| 五月丁香六月在线| 色色婷| 欧美性生交A片免费看| 欧美人人草草| 婷婷99中文字幕| www.狠狠操.co m| 婷婷六月天亚州| 亚洲综合五月天婷婷丁香| 国产激情久久| 五月天综合在线网| 亚洲有码在线视频| 欧美激情丁香五月| 偷拍视频五月天| 婷婷成人视频| 97人人草| 丁香五月WWW| 色999五月色| 日韩精品色| 91精品久久久久久久久| 大香蕉久操| 影音先锋91视频| 成人精品在线| 99热日韩| 五月天婷婷丁香| 男女av免费看| 青青热视频| 九九爱激情| 婷婷色五月天在线观看| 婷婷五月天成人视频| 九九久久99精品免费观看www| 婷婷六月丁香久| www.五月天| 极品少妇高潮啪啪AV无码| 99热99| 中文久久久人妻| 99这里只有精品| 国产黄大片在线观看画质优化| 五月亭亭欧美女人| 午夜性爱影视一区77| 色色色地址| www,婷婷,com| 亚洲色色色色色色色色色| 婷婷五月情天| 国产精品美女久久久久AV超清 | 六月婷婷五月丁香首页| 五月天激情图片| 欧美日韩欧美| 91碰碰视频| 婷婷开心久久| 欧美大片免费播放器| 久久婷婷色情7777网站| 五月 婷婷 成人| 久9热| 原琪琪色影院| 99精在线| 五月婷婷色在线| 99色精品视频| 9久国产精品| 丁香五月婷婷综合激情啪啪啪| 激情五月天啪啪视频| 五月婷婷偷拍| 色色色天堂网| 伊人久久五月天| 五月天激情婷婷| 久久婷婷激情| 极品人妻VideOssS人妻| 这里只有精品96| 台湾综合丁香五月蜜桃| 色情五月综合婷婷| 色欲久久久久久综合网综合网| 四色女婷婷| 99久久九九| 伊人久久艹| 99九九玖玖| 91日精品| 精a品a| 婷婷丁香五月视频| 开心五月丁香啪| 性做久久久久久久免费看| 婷婷丁香五月综合| 婷婷五月天堂| 91色逼| 久久综合首页| 婷婷终合色图| 99热这里是精品| 天天艹| 久久久久久久久人妻| 狠狠婷婷综合| 五月丁六月婷| 日本色啪| 性天天中文网| 亚洲啪啪自拍| av操一操| 97人人操人| 久久99精品久久只有精品| www.99操.com| 丁香五月激情啪啪| 色色色天堂网| 六月婷婷色综合| 久久久久久久久久久44| 婷婷五月草| 97人妻碰碰碰久久| 五月丁香六月色| 26uuu丁香婷婷五月| 成人综合视频在线| 久色网址| 色五月亚洲| 婷婷久久午夜网| 超碰99在线观看| 日本va网站| 欧美色男人网站| 丁香婷婷色五月天| 五月天激情日色在线| 99热这里只有精品在线观看| av无码电影| 久久婷婷色色| 色色日韩网| 嫩草AV久久伊人妇女超级A| 色五月在线| 久久九九激情五月天| 久久A V无码视频| 亚洲AV另类| 亚洲六月婷婷| 色婷婷婷av| 亚洲精品国产A久久久久久| 日本性激情色播| 丁香五月婷婷久久久| 97av在线视频| 婷婷丁香六月| 婷婷五月天深爱| 人人操婷婷| 丁香五月天社区| 色香蕉影院| 免费观看全黄做爰的视频| 99愛国产| 激情丁香九九五月综合网| 99精彩视频| 婷婷激情欧美| 丁香五月婷婷亚洲另类| 婷婷午夜| 深爱激情久久| 97电影99热| 狠狠狠狠狠狠| 婷婷五月天综合色| 狠狠爱婷婷爱| 日日做A爰片久久毛片A片英语 | 日日夜夜狠狠| 天天操夜夜爽天天操| 69凹凸成人综合网| 色婷婷先锋| 99re在线观看视频| 大香人妻| 婷婷基地爱| 亚洲久热无码| 久久婷婷五月丁香网| 国产精品扒开腿做爽爽爽A片唱戏 亚洲爆乳无码精品AAA片蜜桃 | 情色婷婷五月天| 日本va网站| 九草性爱| 狠狠干,狠狠操| 婷婷五月天开心网| 丁香五月在线人妻| 991自拍视频| 五月丁香综合在线| 少妇人妻综合色6699| 丁香五月婷婷啪啪啪| 五月婷婷丁香日韩在线| 亚洲在线操| 久久在线人妻| 亚洲无码另类| 狠狠狠狠草草| 丁香六月婷| 成人va在线播放| 99er免费在线观看| 大香蕉五月| 《亚洲操B久久免费在线观看,亚洲操B久久在线播放》在线播放 - 高清资源 - 97 | 激情五月婷婷| 欧美色五月| 我爱宗和色| 亚洲旡码| 1024在线观看免费视频| 欧美日综合| 色五月婷婷大香蕉| anquye五月| 亚洲午夜精品久久久久久人妖| 久久无意婷婷| 色婷婷亚洲婷婷| 色综合久久中文| 色天天综合| 韩国情人在线电视剧免费观看高清版全集| 欧美啪啪五月天| 少妇大叫太大太粗太爽了A片| 4399亚洲视频| 人人综合久| 激情婷婷狠狠干综合| 亚洲成人综合在线| 婷婷五月天在线视频网站| 9999热这里只有精品| 人妻久久久久久久久妻久久久久久久久| 久艹伊| 色五月丁香A欧美com| 亚洲AV免费在线| 日韩无码专区| 色婷久| 五月丁香六月婷婷欧美综合| 色五月视频无码播放| 成人五月天在线观看| 五月色婷婷影院| sewuyuetingtingiii| 五月丁香另类网| 五月婷婷涩涩爱| 超碰精品在线| 97av在线视频| 996热re视频精品视频| 中文字幕 中文字幕明步| 永久地址 色| 黄涩毛片| 天天做天天双| 婷婷欧美色| 九九伊人网| 五月婷婷丁香综合| 站长推荐无码播放| 婷婷九九视频| 五月久久| 加勒比久热| 91碰操| WWW.五月com| 久久婷婷一级片| 日本色色色色色色色色一色二色| 婷婷五月在线视频| 99操| 丁香六月婷婷久久综合| 激情五月天色色网| 九九久久精品| 91九九| 成人精品一区日本无码网| 激情综合五月| 无码激情AAAAA片-区区| 欧美成人精品A片免费一区99| www.婷婷六月天| 欧美这里只有精品| 丁香五月激情综合| 色婷婷六月| 99国产精品久久久久久久久久久| 婷婷久久五月| 五月综合激情婷婷六月色窝| 无码99| 亚洲这里只有精品| 色色热| 9色在线视频| 操人91| 婷婷成人视频| 开心五月婷婷| 国产婷婷婷| 久久九九99.www| 日本理论久久| 91丨九色丨熟女丰满| 日韩另类| 一区二区中文字幕| 伊人五月人妻精品| 五月丁香龟婷婷| 婷婷五月婷婷| 色色丁香婷婷| 色九区| 久久中文网| 97久久超视频| 五月婷婷偷拍| 色色综合成人网| 亚洲 无码 中文字幕 中出| 亚洲色vA| 色五月综合| 九九AV| 伊人在线视频| 五月婷九九草| 久久99久久99精品免观看粉| 99色6爱9热| 婷婷五月中文字幕国产| 99久热这里只有精品| 久久久.COM| 丁香五月影院| 日美三级| 99久久综合网| 啪啪啪五月天| 99热都是精品| 五月激情六月丁香| 女同在线9| 色人久夂| 狠狠色官网| 色色网站| 99热这里只有精品8| 五月激情四射网站| 伊人久久大香线蕉av一区| AV色五月婷婷| 丁香五月六月婷婷殴美综合| 五月丁香激情婷婷| 国产高潮A片羞羞视频涩涩| 黄色aa观看aaguochan| 超碰日日操| 婷婷五月天视频小说| 亚洲久久激情| 午夜丁香| 男人天堂AV在线一区二区| 五月丁香综合啪啪| 99热中文字幕久久| 婷婷六月丁香五月| 久久五月丁香综合| 九九碰九九爱97超碰| 色情五月天婷婷| 爱操人妻| 99视频在线观看地址| 亚洲操操操| 婷婷六月偷拍| 五月天婷婷色色| 思思热精品在线观看| 天天玩夜夜操| 99视频在线看| 色五月婷婷少妇人妻| 99热66| 日韩黄色影院| 97久久超碰| 99热这里只有精品搜| 色综合伊人网| 超碰国产在线观看| 色综合久久伊伊婷婷五月| 玖玖午夜视频| 伊人狼人干| 亚洲小视频免费看| 激情网五月天| 午夜伊人大香蕉| 亚州精品色情无码A片| 5月婷婷6月六月丁香| 大地资源色婷婷视频在线| 六月丁香色色色| 热99热9| A久久| 成人视屏在线观看| 日狠狠| 五月停性愛| 日本激情ⅩXX免费视频| 婷婷五月天基地| 色婷婷香蕉在线| 色色亚洲无码| 嫩草视频在线观看| 日本97久久久精品| 性生活视频98791| 四LLL少妇BBBB槡BBBB| 日韩婷婷| 殴美综合激情五月天免费视频| 一二线视频 另类| 五月婷婷偷| 99久久综合网| 狠狠色丁香婷婷久久综合| 婷婷五点亚洲| 狠狠爱青青草| 密臀久久| 深爱综合网| 亚洲成人一区| 99热免费精品| 1024成人在线观看| 思思热高清在线观看| 久月久在线视频| 天天插天天日天天爽| www.夜夜| 伊人激情啪啪| 中文AV在线播放| 九九综合网色全集 | 激情五月天啪啪视频| 亚洲五月婷| 日韩久热| 99A级片| 开心五月婷婷婷美女| 精品人妻伦一二三区久| WWW色色色COM| 99性爱精品| 成人AV片播放| 狠狠色丁香久久婷婷综合五月| 91精品激情9| 天天综合五月| 香蕉97碰碰碰欧美| 操逼福利视频| 欧美性猛交99久久久久99按摩| 99高级会所久久| 天天爽天天| 婷婷五月天,影院| 欧美电影在线观看| renre人人操国产超碰在线| 亚洲第一综合| 激情五月婷婷网在线观看| 国产乱子轮XXX农村| 婷婷六月丁香久| 午夜69成人做爰视频| 极品人妻videosss人妻| 国产午夜成人免费看片无遮挡| 六月婷婷七月丁香| 久色婷婷200| 无码一区二区三区四区五区91c| 欧州色色| 丁香六月婷婷开心婷婷网| 97色色色| 色婷婷777狠狠| 丁香六月婷婷综合| 五月天婷五月天综合网小说首页-五月天激激婷婷大综合,婷婷亚洲综合五月天小说 | www.99热视频在线观看| 69久热| 99啪在线视频| 亚洲免费av在线| 五月丁香六月婷婷啪啪| 亚洲激情视频在线观看| 91婷婷丁香五月天免费视频网站| 丁香五月婷婷基地| 日日操夜夜爽天天天| 色五月婷婷777| 激情五月开心五月丁香五月| 狠狠色大香蕉| 97操在线视频| 色六月天天激情综合网| 激情内射人妻1区2区3区| 久久亚洲婷婷| 91久久免费| 99久re热视频精品98| 日本五月婷婷久久久六月丁香| 激情操逼婷婷| 五月丁香六月色| 激情色色| 变态 另类 在线| 26uuu亚洲| 婷婷色播婷婷| 一本道在线电影| 可似看的AV| 欧美日朝成人| 少妇被下春药玩弄A片| 婷婷亚洲欧美丁香五月| 99在线视频播放| 丁香六月婷婷久久综合| 毛片毛片毛片毛片| 性视频久久| 裸睡玩奶头(高H)| 色深爱五月| 99视频内射三四| 牛牛热这里只有jingpin| 26uuu成人网| ay2区| av超碰在线| 婷婷色婷婷| 五月天激情日色在线| 99热综合色图| 双性美人被调教到喷水A片| 99热6色| 狠狠做五月| 色约约视频一区二区三区四区五区 | 日韩a热| 丁香五月婷综合| 天天爽天天操| 99热免费在线| 思思99精品视频在线观看| 五月天AV大香蕉| 国产AV一区二区三区最新精品|