免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

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
返回資訊列表
九九一区| 色播五月丁香综合| 日本婷婷色日| 26UUU| 婷婷狠狠操| 五月天婷亚洲天综合网综合| 久久精品日| 日本高清久| 九九操操| 性爱五月婷| 色色日本欧美| 丁香婷婷激情网站| 色综合色综合婷婷热| 日韩艹比| 深爱激情五月天| 色婷婷色人人射| 久久五月天网| 色五月丁香A欧美com| www.婷婷,com| 久久黄色网扯| 思思热这里只有精品视频666| 亚洲亚洲人成综合网络 | 安息电影在线观看完整版| 国产日产亚洲系列最新| 九九热视频精品| 五月综合激情视频| 伍月激情天| 激情婷婷视频在线| 五月天婷婷婷| 国产精品久久久久久久久久免费| 色色网站| 色99在线视频| 五月天综合激情网| 99在线热视频| 另类激情五月在线视频欧美| 噜噜色婷婷| 婷婷五月天亚洲色| 六月色伊人婷婷| 国产精品色婷婷久久久精品| 操日本色| 超碰精品国产首页| 奇米网大香蕉| 色婷婷色和| 一本大道嫩草AV无码专区| 天堂网啪啪| 天天摸天天日天天舔| 亚洲五月天综合色| 婷五月天天| 国产4P视频精品五区| 嫩草AV久久伊人妇女超级A| 六月婷婷av| 婷婷性色| 亚洲激情综合| 色婷婷亚洲婷婷| 激情综合网激情五月欧美| 久激情网| 五月噜噜噜色综合| 五月婷婷 六月丁香| 国产精典视频在线观看| 午夜大香蕉| 日本色久| 色色色激情| 99啊精典免费视频| 区美毛片子| 色色色色色五月| 97涩婷婷婷婷基地| 99九九视频精彩在线| 久草视频大香蕉99| 丁香玖玖| 免费视频舔| 久9精品视频| 人人性久久| 嫩草国产| 久热这里只有精品3| 超碰在线观看99| 综合色五月| 婷婷99热| 丁香五月视频在线观看| 亚洲视频图片婷婷五月| 91凹凸在线| 97碰人人操| 丁香五月天的网址。| 亚洲婷婷激情888精品久| 丁香五月日啪| 丁香色婷婷五月天| 激情久久久久久久久| 欧美性丁香色色五月天干干| 亚洲精品午夜国产va久久成人| 色五月天激情| 五月婷婷激情在线| 五月婷婷干干干| 欧美在线看| 综合久久婷婷| 国产精品蜜臀99| 久久性爱视频这里只有精品| 色五月婷婷色| 日韩在线视频9色| 婷婷五月天丁香久久| 99亚洲色| 99re热在线视频观看| 91婷婷搞| 五月天自拍视频| 精品少妇蜜臀91| 精品A√| 久婷五月| 欧美人与性动交CCOO| 思思久久久婷婷| 婷婷丁香黄色| 婷婷大美在线| 激情综合色婷婷啪啪六月天| 九九九九精品精| 久婷自拍视频| 亚洲激情五月婷婷日日| 欧洲亚洲免费视频9| 日本天天色| 婷婷五月天伊人| 六月婷综合| 性色婷婷| 激情五月婷婷开心网| 操逼视频一区| 狠狠色婷婷丁香五月| 久久婷婷五月天激情四射| 久热这里只有精品在线观看| 99热免费| 日韩天堂久久| 男人的天堂五月丁香| www.五月婷婷久久.com| 国产AV不卡福利| 日韩一区二区在线播放| 色狠狠综合网| 国产操B视频| 午夜九九电影| 丁香六月欧美| 九九re精品视频在线观看| 色天天综合色| 色婷婷综合网| 久久五月婷婷丁香| 高清无码视频网址| 亚洲国产网址| 99久久综合精品五月天| 五月丁香网站| 九九热10| 天天躁日日躁狠狠躁日日躁2022年5月9日 | 婷婷丁香五另类网站| 久久99综合网| www久久99| 亚洲99在线| 亚洲成人AV电影网| 九九99久久| 天天射天天操天天干| 久久99热这里只有精品23| 丁香大香蕉| www.99精品视频| 久久五月天色| 99黄色在线视频精品熟女| 婷婷天天色| 9l视频自拍九色9l黑人| 人妻精品一区二区三区| 久久婷丁香五月| 先锋资源婷婷| av 一区三区四区| 狠狠操狠狠操AV| 国产免费AV网站| 99ri在线观看视频| 欧美激情丁香五月天久久婷婷一区| 五月丁香六月激情| 久久人人人人妻| 蜜臀久久99精品久久久久久酒店| 六月丁香五月天| 精品自拍97| 99这里只有精彩视频| 激情综合网激情五月婷婷| 丁香五月在线视频黑人| 99九九中文字幕视频| 狠狠色大香蕉| 99热精品网| 久久精品99国产精品日本| 婷婷六月综合在线| 久久亚洲天堂| 激情99| 色五月五月丁香| 丁香婷婷天堂| 九艹在线| 五月丁综合在线观看| 91人久| 婷婷六月花| 婷婷丁香五月天熟女丝袜| 丁香五月成人婷婷| 91艹人| 久久婷婷五月综合色丁香花| 婷婷97碰碰| 国产中文亚洲欧美日韩性交| 久久婷婷五月综合色天| 久久久久久久人妻| 婷婷无码五月天| 9l视频自拍九色9l视频自拍九色9l社区| 九九自拍网| 日本色婷婷| 国产精品色色色色| 大香蕉久| 无码一级片| 色一情一乱一乱一区91| 欧洲免费视频色| av在线免费网站| 激情六月综合| 夜夜骑夜夜操| WWW激情五月天| 97九色视频| 99热这里只有精品8| 久热网站| 五月婷婷色丁香| 色吊丝中文字幕| 99亚洲天堂| 激情综合网 激情五月天| 国内久久亭亭| 在线五月婷| 五月婷婷欧美| 婷婷色综合| 成人无码精品1区2区3区免费看| 操射国产日本| 婷婷五月天va| 婷婷五月天成人在线视频| 久久91久久精品久久| 色婷婷综合影院| 狠狠擼综合| 天天色99| 99热精品超碰| 色播激情| 91久久国产自产拍夜夜91久久精品文字>91麻豆精品国产 | 激情av网| 色色色宗合网| 亚洲 在线 另类| 久9热| 五月天亚洲色| 99久久激情视频| 思思久久精品视频| 玖月婷婷爱丁香| 日韩黄色网络| 99熟女| 99亚洲日韩| 天堂爱爱| 五月婷婷六月丁香综合视频在线| 99久久九九| 热婷婷久| 婷婷九月丁香天堂丁香天堂| 久久伊人婷| 久草丁香婷婷1024| 亚洲精品第一国产综合亚AV| 色综合久久久无码中文字幕999| 99这里| 久久婷婷网| 婷婷五月激情视频在线| 五月丁香另类图片| 婷婷婷婷婷婷婷婷| EEUSS鲁片一区二区三区| 欧美97p| 五月情四婷婷| 97婷婷丁香五月| 深爱女色婷婷丁香五月亚洲图区| 涩涩五月天综合| 婷婷丁香社区网| 五月婷婷色色| 久久久婷婷| 这里只有精品免费视频| 国产一级片| 一起草AV| 免费无码毛片一区二区A片| 丁香五月婷婷五月| 欧美性生交A片免费看| 久久久97| 青青草大香| 成人综合视频网址| 亚洲成人无码免费| 欧美大香蕉视频| 97色天堂| 五月丁香综合啪啪啪啪啪| 人人草成人视频| 一起草无码视频| 青青草a在线| 二人电影免费版在线观看| 五月天激情小说婷婷| 五月丁香猫咪久久婷婷综合视频激情四射网入口 | 色噜噜狠狠色综| 在线18av | 老美AA片| 国产操肏网站| 五月激情丁香久久综合网| 思思热久在线观看视频| 婷婷五月天成人小说| 五月婷激情| 激情人妻综合| 中文字幕日本最新乱码视频| 婷婷va| 色色丁香五月天| 那里有AV网址| www激情com| 99热这里只有精品8| 色婷婷97| 五月 婷 久| 99ri视频在线播放| 五月激情开心婷婷| 久久思思热| 99热国产免费| 久久91久久91色欲精品| 日本精品。999| 操丝袜视频影院导航| 97干在线播放| 亚洲精品操一操、噜一噜、摸一摸、爽 | 琪琪色综合网站| 久草丁香婷婷五月天婷| 狠狠干2007| 五月天天爽| 99热9| 超碰成人黄色网| 五月天婷婷社区久久综合| 91狠狠综合久久久久久| 夜夜撸夜夜骑| 97日韩无套内| 俺也去在线久久精品23欧美综合视频网站,丰满人妻一区二区三区在线视频53,丰满 | 日日操夜夜爽白洁| 五月婷婷色综图片| 免费一区二区三区| 婷婷丁香成人在线视频| 超碰91在线| 激情五月狠狠| 欧美槡BBBB槡BBB少妇| 亚洲色区17| 五月色丁香综合| 色情五月婷婷| 97色射| 97干在线视频| 97色色综合| 狠狠爱深色婷婷综合| 亚洲小电影在线观看黄999| 热久久66| 久碰视频| 九九热这里有精品视频| 亚洲超碰在线| 182TV亚洲| 精品久久久久久久人妻| 思思9久久| 看黄的网站18禁| 天天爱天天操| 激情久久月| 色丁香久综合在线久综合在线观看| 久久免费操| 狠狠色综合久久久久| 另类色网| 俺去也在线www色官网| 欧美成人A片AAA片在线播放| 婷婷综合激情| 久久这里只精品| 久久婷婷色情7777网站| 久久久久网站| 丝袜激情网| 丁香五月激情在线| 亚洲国产成人AV在线| 夜夜夜夜做天天天做无码视频| 五月天色社区| aaa丁香五月天| 色婷婷综合久久久久| 丁香六月青青草| 色婷婷久久综合丁香五月| 少妇AB又爽又紧无码网站| 激情小说五月天社区丁香| 婷婷涩五月| 久9热视频在线观看| 丁香色五月天| 婷婷色五月激情强奸四射| 色色色色热| 色五月天丁香婷婷色| 可以免费看AV网站| 五月天另类图片区99| 99热这| 激情六月天| 1024成人在线观看| 91丨九色丨大屁股| 狠狠人人| 久久这里只有精品视频15| 色五月婷婷婷婷| 亚洲视频综合网| 99色一| 日韩中出视频| 99视频九九热| 婷婷五六月丁香| 少妇性按摩无码中文A片| 九月婷婷丁香| 97人人操人人干| 五月丁香亚洲校园欧美| 国产美女无遮挡裸体毛片A片| 五月天激情Av| 极品九九九九九九| 亚洲综合激情五月久久| 一个色的综合| 婷婷丁香社区| 九九香蕉网| 六月伊人婷婷| www.色色五月天.com| 丁香五月在线自慰| 少妇2做爰HD韩国电影| 五月丁香婷婷伊人| 色婷婷久久综| 日本精品人妻无码77777| 丁香五月婷综合网| 99综合免费视频| 亚洲精品V天堂中文字幕| 天天影视色综合网| 99热在线精品观看| 99热10在线高清播放| 这里只有精品视频免费在线观看| 五月丁香日本一抹本| 91九色最新视频| 九九無妻| 天天摸夜夜爽天天做| 亚洲蜜乳AV| 婷婷丁香18| 国际国外精品欧洲南美洲专区无码不卡| 五月婷婷国产| 麻豆AV一区二区三区| 噜噜狠狠色| 性爱在线播放av| 五月婷婷深深爱| 婷婷综合久久| 婷五月天六| 色墦五月丁香| 九热免费视频| 婷婷深爱五月丁香| 婷婷丁香五另类网站| 香蕉大综综综合久久| 人人爱操| 色色色999| 六月丁香色婷婷| 伊人影音无码一区二区三区| 极品另类| 成人在线免费网址| 九九无码AV| 色五月综合网| 91婷婷色| 婷婷婷婷婷婷婷婷| 五月花综合视频| 丁香五月狠狠在线观看| 成人精品在线| 久久久久8888| 色色丁香婷婷| 超碰资源在线| 婷婷丁香十月| 草逼大片| 亚洲欧州色情在线观看| 激情五月天之六月婷婷| 激情综合五月激情17| 亚洲成人网站在线| 丁香花婷婷五月天| 无码人妻一区二区一牛影视| www.色色色com| 中文字幕网伦射乱中文| 婷婷五月天天爽| 久热这里这里有精品| 激情宗合 激情宗合| 婷婷丁香综合网| 婷婷五月天综合网| 99只有精品| 99热这里只有精品22| 五月丁香六月激情| 婷婷激情人妻| 变态另类9| 五月天激情网站| 国产综合网在线| 丁香5月婷婷| 日本九九热| 五月在在观看| 九九无毛| 色五月美女| 婷婷综合天堂| 亚洲AV无码一区二| 九九热99视频在线| 久久婷五月婷| 伊人五月天日日夜夜久久久天天| WWW丁香五月| 亚洲激情综合色站| 深爱婷婷色| www.狠狠狠狠| 久久五月婷婷视频| 色老久久| 婷婷丁香人妻天久久| 日本99热| 婷婷激情五月综合基地| 婷婷丁香五月亚洲综合网在线视频观看| 天天天添天天操| 丁香婷婷五色月| 天天干天天操天天上| 三级大香蕉网| 色婷婷亚洲婷婷| 26.uuu丁香五月婷婷| 激情丁香婷婷| 女人高潮内射99精品| 99热网精品| 色九月综合| 亚洲另类毛片| 亚洲成人综合在线| 99爱免费视频在线观看| 久久激情天堂| 婷婷久久综合| 色色综合院| www.精品99| 99久久a线观| 超碰丁香五月| 九九黄色网| 亚洲五月六丁香激情| 俺去也在线www色官网| 五月婷婷视频| 大地9中文在线观看免费高清| 亚洲AV成人一区二区在线观看| 婷婷久久图片| 婷婷五月天激情偷拍| 激情五月婷婷色| 丁香六月啪啪啪| 激情五月综合| 99热九九在线| 综合性视频99| 丁香五月天在线观看视频| 五月婷婷久久综合| 六月婷婷综合激情| 色狠狠色噜噜AV天堂五区| 东北熟女高潮99综合99| 久久婷婷六月| 久久综合婷婷五月| 超91热| 亚洲第一成人无码A片| se99在线| 人妻AV在线| 久久视频在线| www.狠狠操| 五月丁香婷婷99| 激情五月丁香综合蜜桃| 九九色播五月丁香| 99在线看视频| 天天插天天很| 久久五月天婷婷| 五月婷婷黄色毛片| 六月丁香五月激情网| 99精品视频偷拍| 日韩啪啪视品| 激情综合网,五月| 伊人狠狠丁香婷婷综合尤物| 丁香五月婷婷香| 狠狠88综合久久久久噜噜噜| 婷婷色网站| 九九久99免费视频| 丁香色情五月综合网站| 国产毛片欧美毛片久久久| 五月天丁香婷| 婷婷五月天美女21p| 大伊香蕉精品视频在线| 五月天国产成人| 久久总和99| 99超级超级超级碰| 狠狠撸激情综合丁香五月天俺来啦| 六月婷婷六月天天在线免费| 色婷婷久久久| 中文字幕九九九九| 国产免费一区二区三区三州老师F1F1.CC | 五月婷婷99热| 无码区婷婷五月花开| 丁香五月婷婷亚洲激情四射| www.亭亭五月天| 国产小精品| 五月天婷婷六月激情网| www.婷婷五月天.com| 六月婷婷激情图片| 大香蕉九操| 91成人看片| 六九色综合婷婷五月天| 性爱激情小说AV五月丁香花| 99精品热| 婷婷五月色影视先锋| 婷婷国产成人| 视频一二区| 99热碰碰| 大香蕉婷婷色| 99亚洲视频| 久久er视频6| 久久丁香五月天| 色色是色N一| 久久婷婷五月天| anquye伊人| 精品一二三区久久AAA片| 五月色丁香综合| 丁香五月天啪啪| 色色色视频免费无码| 熟妇人妻中文字幕无码老熟妇 | 在线99热| 99热这里只有在线播放| www.91av.com| 久久久性爱视频| 亚洲无码成人网| 99色网站| 久久精品在线| 91九色 熟| 色婷婷五月天| 综合五月草| 成人午夜天| 五月丁香花开综合网| ady狠狠入| 99日本黄站| 激情五月天在线| 99九九这里有免费视频| 99在线精品视频| 日韩人妻无码专区| 懂色av粉嫩av蜜臀av| 99热精品中文字幕| 性日本激情| 五月丁香婷婷俺| 日韩无码91| 97色色婷婷| renre人人操国产超碰在线| 亚洲AV无码电影| 99精品一二三四视频| 高清无码.com| 第四色色色色色丁香五月天| 婷综合| 99热在线中文字幕| 99 re视频一区| 国产XXXX搡XXXXX搡麻豆| 国产午夜一区二区三区| 成人AV在线中文版| 99热资源在线| 五月天伊人日日噜影片AV| 色欲色香综合网站| 99操视频| 丁香婷婷色情| 亚洲综合婷婷五月| 丁香色色色| 伊人大香蕉爱聚| 武则天精品久久| 5月丁香六月情| 91婷婷色 | 新激情婷婷| 91欧美日韩综合| 五月激情五月婷婷五月天在线| 99自拍网| 五月伊人婷婷999| 五月丁香啪| 亚洲五月丁香六月婷婷| 91小黄书网址在线观看| 五月丁香| 色色色色色色色色色色色色色97| 婷婷综合中文| 婷婷激情五月综合| 色综合激情| 亚洲五月天婷婷| 人妻肉射免费观看| 人人爱干人人爱草| 亚洲精品国产成人AV在线| 碰人人97| 婷婷伊人欧美| www.五月天| 99热6精品| 欧美成人日韩| 热99在线| 亚洲色色香蕉| 婷婷丁香五月天在线| 天天射夜夜爽| 久久综合九九| 欧美色色色色色| 日日操夜夜操无码免费| 夜夜AVV| 丁香婷婷综合影院| 久久九九热re6这里有精品| 欧洲亚洲欧洲99久久| 欧日美女Va| 超碰在线看| 丁香五月日韩| 日韩精品999| 婷婷终合色图| 91|九色|动漫| 久久艹99| 色色激情网| 97碰碰视频在线观看免费| 六月丁香婷婷色狠狠久久| 亚洲 欧洲 国产 伦综合| 影音先锋五月天婷婷丁香在线观看| 香蕉AV777XXX色综合一区| 中文字幕欧美日韩VA免费视频| 狠狠草在线观看| 99激情视频| 99re这里只有| 伊人激情AV一区二区三区| 丁香五月偷拍| 91干婷婷| 九九热青青草| 九九热99免费视频| 婷婷激情综合| 婷婷第六色| 久这里只有精品| 大波美女VA网站| 狠狠操.COM| 女人天堂 AV| 婷婷五月天六月丁香| 99色综合| 天天天干夜夜夜操| 午夜69成人做爰视频| 老妇六区| 欧美久人人| 99热碰碰热| 九九热这里只有精品556| 色婷婷丁香五月在线| 六月天六月婷| 色色狼人综合| 免费成人va| 99视频精品全部免费观看| 五月丁香激情婷婷| 色综合综合色| 江苏少妇性BBB搡BBB爽爽爽| 99碰碰中文| 一区色色色色网| 久久久五月激| 色色国产| 人妻少妇色综合| 99riAV成人在线视频| www.久久9| 9er热在线精品视频| 丁香五月婷婷成人网| 99熟女啪啪视频| 狠狠操天天干| 亚洲av成人一区二区电影在线| 综合久久高清| 26uuuu精品一区二区| 色色色色色色网站| 久久久久9999| 色色五月激情| 亚洲色婷婷激情| 来吧亚洲综合网| 六月综合婷婷开心伊人| 丁香色情五月综合激情| 五月色婷婷在线观看| 天天爽天天草| 激情婷婷丁香色五月综合| 91成人性爱视频| 九九综合久久| 日韩精品超碰在线观看| 欧洲亚洲欧洲99久久| 久久九九@| 激情人妻蜜夜系列区| AAA久久久| 婷婷五月天综合中文| 4399成人黄A片| 操操熟女| 99精品网站| 九九综合久久| 玖玖精品婷婷| 天天干天天色天天干| 色五月丁香网| 99久精品视频| 久久机热/这里只有精品| 国产精品国产成人国产三级| 欧美 日韩 成人在线| 婷婷五月天堂一本在线| 亚洲亚洲人成综合网络| 五月激情啪啪啪| 天天操天天曰| 色就色94欧美setu| 六月五月久久丁香| 丁香五月欧美| 色婷| 丝袜激情网| 99热在线网站| 激情五月深爱婷婷| 午夜不卡久久精品无码免费| 熟女乱论网| 婷婷色五月丁香六月欧美啪| 丁香玖玖| 色99色| 丁香五月婷婷久久久| 另类激情五月| 色噜噜狠狠狠综合曰曰曰| 成人国产欧美大片一区| 五月天婷婷久久日| 五月天六月色| 99色综合| 日日撸夜夜操| 久久五月丁香婷婷| 久久六月综合| 97色色色色色色色| 婷婷久久五月天| 婷婷色色网| 精品五月天| 久久伊人五月天| 色五月婷婷中文字幕| 棕合影院色色| 最新av在线观看| w婷婷五月婷婷w| 99九九精品视频| av在线中文| 天天操无码| 91色久| 天天干,夜夜爽| 久久99这里| 农村熟妇高潮精品A片| 日韩av干| 婷婷五月丁香色色| 狠狠草狠狠草| 激情六月天婷婷| 99日韩| 中文字幕丰满乱孑伦无码专区| 噜噜噜狠狠色综合| 深爱激情五月天婷婷网| yirenjiqingshiping| 激情五月天无人视频在线| 99热官网精品在线| 99热亚洲| 视频免费精品免费精品免费精品免费精品免费精品免费精品免费99 | 国产暴力强伦轩1区二区小说| 色色丁香五月婷婷| 丁香五月成人自拍| 超碰色色综合| 这里只有精品热| 草草色情综合网| 婷婷五月天激情基地| 1区2区视频| 99久久综合| 5月婷婷激情6月| 婷婷五月丁香激情图片| 91无码视频| 亚洲综合色网站| 丁香婷婷综合影院| AV在线观看网站| 婷婷丁香五月天综合网| 91 久热| 九色91国产| 伊人五月天日日夜夜久久久天天| 99热有精品在线观看| 人人摸人人干| 台湾综合丁香五月蜜桃| AV中文字幕夜夜操b天天摸bb| 五月天婷婷爱| 人色五月天婷婷| www91久久| 婷婷综合网| 五月婷婷 激情五月| 久久久18| 麻豆123区| 欧洲亚洲精品| 看久久性爱99视频| 少妇丁香婷婷 | 操逼巨乳91| 亚洲第一色色色色| www.97干视频| 性欧美大战久久久久久久83| XX久久| 99视频精品全部免费观看| 日本三级日本三级三级人妇四虎| 亚洲综合网在线| 久久久91| 啪啪亚洲综合| 玖玖伦理电影| www.99日本| 国产97在线日韩亚洲女人被黑人巨大| 亚洲AV成人片无码网站| 2025年最新亚洲在线欧美| 色情五月婷婷| 欧美丁香五月| 亚州男人天堂婷婷五月| 来吧亚洲综合网| 久久免费精彩视频| anquye五月| 99在线观看视频免费| 2022人人操人人看| 天天干天天av天天射| 亚洲操逼网| 综激情网| 五月丁香婷婷AV| 五月婷婷六月奇米网丁香| 色综天天综合| 国产ava| 婷五月天六| www.91热久久| 少妇水多A片太爽了| 色情五月综合婷婷| 亚洲网视屏| 天天草天天爽| 99亚州综合精品成人网| 五月婷婷狠狠干| 婷婷区日本| 亚洲综合视频天天精品| 久久草大香蕉| 日韩成人中文字幕| 亚洲色激情| 十区av| 69人人操人人爽| 久久91久久精品久久| 人妻内射一区二区在线视频| 天天插天天干| 97色色视频| 丁香五月成人社区| 夜夜骑夜夜操| 五月天婷婷在线播放| 狼人久草| 久久久精品色| 99这里只有精品视频| 色色五月天婷婷| 久久亚洲婷婷| 99re思思热久久| 91碰碰碰| 久久色情| 无码少妇高潮喷水A片免费| 欧美性猛交AAAA片黑人 | 天天干一干| 成人做爰A片免费看视频| 国产成人精品一区二三区熟女在线| 激情五月综合六月丁香婷婷狠狠干| 樱花99视频| 深夜婷婷五月丁香| 天天色天天噜| 天天综合影院| 精品色色| 99久久99九九九99九他书对| 99视频自拍| 开心五月激情网| 五月婷婷综合在线| 色涩视频久久| 視频福利乱色| 五月婷婷色影院| 五月婷丁香花| 噜噜噜色噜噜| 另类小说激情五月天| 色99在线观看| 狠狠色综合网| 国产AV一区二区三区日韩| 久久婷婷五月综合色欧美| 99综合99| 爆乳熟妇一区二区三区爆乳照片| 色播丁香| 亚洲成人乱码av网站| 99热.com| 91狠狠色丁香婷婷综合久久精品| www.五月天| 五月天激情亚洲| 91成人电影| 五月丁香六月婷婷,婷| 99免费视频在线观看爱| www.97碰碰com| 精品婷婷| 4438全国最大视频成人网站在线观看| 91综合色| 五月丁激情| 久热免费| 五月丁香激情综合网| 伊人激情综合| 成人短视频在线| 色国产五月| 色久丁香五| 激情五月天色色网| 丁香九色不卡aaa| 亚洲激情网| 婷婷五月丁香综合人妻| 亚洲综合婷婷| 97色精品视频 | 久久久久9999| 五月天色色色色色| WWW夜夜| 婷婷丁香18| 激情又色又爽又黄的A片| 综合色吧| 色高清无码视频| 原琪琪色影院| 激情综合色婷婷啪啪五月天| 9色视频在线| 狠狠狠夜夜夜| 伊人综合网站| 欧美色久| 欧美婷婷五月丁香| 九九热精品视频在线观看| 欧美色97| 五月婷婷网站| 婷婷导航| 婷婷亚洲综合| 五月天婷婷激情在线色图| 99国产精品久久久久久久久久久| 婷婷五月色影视先锋| 另类视频丁香五月| 欧美日韩成人在线| 婷婷99狠狠躁天天躁中| 日日插日日干| 欧美性生交XXXXX无码小说| 激情文学久久| 久婷五月| 婷婷五月综合丁香久久| 婷婷丁香五月精品| 99热这里只有精品免费| 九月激情综合| 舔色婷婷| 丁香亭亭激情四射| 五月天婷婷色小说| 99热91| 成人午夜无码视频| 婷婷中文字幕网| 精品视频网| 亚洲综合狠狠艹| 国产古装妇女野外A片| 伊人婷婷青青cao| 99热人人| 色综合九九色综合88| 九九热这里只有精品6| 果冻传媒A片一二三区| 逼逼AV| 欧美性生交XXXXX无码小说| 婷婷,五月天,丁香,第一| 色综合色五月| 五月婷婷狠狠干| 在线观看av网站| 东京热免费视频网站| 婷婷操婷婷干婷婷射| 人妻在线观看视频| 国色天香伊人狠狠色| 狠狠爱青青草| 五月婷婷综合色啪首页| 无码免费人妻A片AAA毛片西瓜| 六月丁香成人| 九九热视频在线观看| 欧洲永久精品| 97色婷婷| www.狠狠狠.com| 国产成人精品亚洲线观看| mmm1717.6dbm人人爱人人操| 丁香五月激情啪啪| 狠狠人人| 《亚洲操B久久免费在线观看,亚洲操B久久在线播放》在线播放 - 高清资源 - 97 | 色五月视频无码播放| 国产性爱在线| 五月深爱网| 一片AV片免费播放| 99久久网站| www.91在线观看| 狠狠香蕉| 婷婷四月 成人 狠狠干| 亚洲无AV在线中文字幕| 激情激情激情网| 丁香婷婷久| 99热这里只有精品9| 亚州操操| 99免费在线视频| 91操操操| 激情五月天第四色| 日本美女上人| 五月激情丁香久久综合网| 中字幕视频在线永久在线观看免费| 思思热久久久久思思热| 婷婷五月天大香蕉在线视频观看| 播播网色播播| 91中文在线| 久久精品国产精品| 五月天网站亭亭| 51XX午夜影福利| 中美月韩免费A片| 国产婷婷综合| 五月婷婷五月色| 久久久jd| 类似婷婷激情综合网站| 丁香五月五月婷婷欧美大香蕉| 五月丁香六月停停| 日韩在线一级| 久久丁香五月| www.99视频| 色五月天综合| 精品久热| 日本丁香久在线| 婷婷丁香18| 99精品网| 欧美精品99| 婷婷丁香六月综合激情站| 久久欧洲综合网| 性一交一乱一交A片久久四色| 五月丁香综合激情网| 五月婷婷六月丁香| 综合网狠狠| 丁香五月欧美| 91精品综合久久久久久五月丁香| 综合久久影院| 最新无毒无码AV| 丁香五月情| 开心五月婷婷在线视频免费观看| 国产婷婷综合| 少妇性按摩无码中文A片| 狠狠狠色激情综合适合| 天天爽天天弄| 丁香五月停停基地| 亚洲精品V天堂中文字幕| 日本狠狠色| 久久久月丁香| 五月婷婷激情性爱| 九九精品丁香花| 色综合五月天| 五月婷婷激情网| 婷婷六月激情丁香| 九九色热| 色婷婷啪啪| 一本色道久久88综合日韩精品| 99热亚洲| 狠狠干综合网| 色999五月色| 欧美久热| 日熟女| 久久人人添人人爽添人人片αV| 六月激情婷婷| 丁香婷五月天开心六月| 色天天综合| 天天综合干| 色婷婷手机在线| 182TV大香蕉| 色综合播放| 婷婷丁香91综合| 久久久婷| 激情综合网五月激情| www.yw色| 天天干天天操天天拍| 婷婷五月天伊人网在线观看视频| 中文字幕综合| 99熟女| 色五月婷婷AV| 国产高潮白浆一区二区| 中文字幕日产A片在线看| 婷婷香蕉| 天堂色婷婷| 成人丁香五月婷| 9 7总站超级碰免费视频| 天天射影院| 婷婷综合激情| 久久五月天综合| 婷婷色中文字幕| 日韩精品999| 欧美日比视频| 日韩在线99| 日韩淑女人妻luan伦激情精品一区二| 亚艹艹| 久久婷婷五月综合色和| 激情综合六月| 亚洲中文乱字字幕线在永久| yazhouzonghesese| 69婷婷丁香午夜| 狠狠狠激情网| 五月天激情中文字幕| 人人摸人人射| va婷婷在线免费观看| 天天射影视综合网| 五月婷婷狠狠干| 色婷婷五月天天天干天天操天天爽| 99热精这里只有精品| 婷婷五月天日日日干干干| 日本成人噜噜噜噜噜| 天天cha成人综合网| 色五月婷婷天天操夜夜操| 丁香婷婷六月激情综合| 丁香五月在线观看完整版| 色操b| 婷婷亚洲欧美丁香五月| 99热国产免费| 天天久久狠狠色综合| 91艹人| 天天草狠狠擦| 天天干天天爽天天爽| 色噜噜狠狠插综合| 久久久久激情网| 久久久激情视频| 婷婷婷婷色| 久草热久草在线视频| 欧州婷婷五月天综合| 丁香五月婷婷高清| 色婷婷五月在线| 久久66er久久| 开心五月婷婷激情网| 色在线视频网2025| 99操免费视频| 五月天激情久久| 六月成人网| 欧美日韩中国| 亚洲精品99| 五月婷婷,六月激情| 日屌日日操日日色| 五月天成人综合| 天天日天天爽| 精品九九久久| 国产ava| 五月婷婷丁香伦理网| 九九精品网| 五月天综合婷婷| 免费三级黄色| 大香蕉Av在线| 色婷丁香五月| 国产综合网在线| 超碰99在线观看| 亚洲春色奇米影视| 婷婷久久影院| 99高级会所久久| 熟女激情五月天| 91精品丝袜久久久久久| 9精品国产在热久久| 婷婷伊人久久| 婷婷五月综合视频| 五月丁香六月婷| 67久久| 99视频精品全部免费看| 五月网网站| 大香蕉久久| 色色色色色日韩午夜激情 | www..com色爱| 色五月婷婷91| www.色多多婷| 日本久久综合| 色狠久| 深爱五月天| 1024婷婷综合久久五月天| 丁香五月婷婷亚洲综合精品在线| 五月丁香婷婷爱| 婷婷色五月91啪啪| 成人av免费观看| 精品人妻一区二区三区四区不卡在| 亚洲丁香花色| 97极品在线| 开心五月深爱婷婷| 无码人妻少妇色欲AV一区二区| 色婷婷激情四射视频| 日本九九热| 五月综合久久| 情色婷婷五月天| 伊人啪啪网| 天天射网站| 99视频超级精品| 99色在线观看视频| 丁香婷婷婷| 日韩婷婷五月天| 亚洲天堂色色| 五月天婷婷免费| 深爱开心激情| 色色色九九九五月婷婷| Xx色综合| 成人在线网址| av第一二区| 色亚洲欧洲| 开心色色五月天综合| www.99热最新视频8| 九九人人操| 五月丁香色婷婷色| 五月天婷婷7米| 亚洲精品九九| 久久99热精品a片在线观看| 深爱五月婷婷| 五月婷婷激情刺激| 超碰在线观看99| 97色女人在线| 六月婷婷五月丁香| 伊人久久大香线蕉综合网站| 色六月视频| 天天色中文字幕女优AV| 婷婷五月天,影院| 五月丁香狠狠爱| 99热99成人| 久久婷婷亚洲| 六月丁香花婷婷| 色日本五月天| 9.1综合网| 综合网激情| 色五月丁香总合网| 久久草大香蕉| 丁香五月另类小说在线阅读| 成人AV在线电影| 夜色综合网|