【C++】C++11 篇二

【C++】C++11 篇二

    • 前言
      • 移動構造函數
      • 移動賦值運算符重載
      • 類成員變量初始化 (缺省值出自C++11
      • 強制生成默認函數的關鍵字default:
      • 禁止生成默認函數的關鍵字delete:
      • 繼承和多態中的final與override關鍵字(出自C++11
    • 可變參數模板
      • 遞歸函數方式展開參數包
      • 逗號表達式展開參數包
    • STL容器中的empalce相關接口函數
    • lambda表達式
      • 實例
      • lambda表達式語法
        • 實例:
        • lambda表達式書寫格式:[capture-list] (parameters) mutable -> return-type { statement }
        • 捕獲列表說明
        • 函數對象(仿函數)與lambda表達式

前言

C++98的6個默認成員函數:

  1. 構造函數
  2. 析構函數
  3. 拷貝構造函數
  4. 拷貝賦值重載
  5. 取地址重載 //用處不大
  6. const 取地址重載 //用處不大

C++111 新增了兩個:移動構造函數移動賦值運算符重載

移動構造函數

如果沒有自己實現移動構造函數,且析構函數 、拷貝構造、拷貝賦值重載都沒有實現
那么編譯器會自動生成一個默認移動構造。
默認生成的移動構造函數,對于內置類型成員會執行逐成員按字節拷貝,
自定義類型成員,則需要看這個成員是否實現移動構造,如果實現了就調用移動構造,沒有實現就調用拷貝構造

移動賦值運算符重載

(默認移動賦值跟上面移動構造完全類似,把移動構造函數替換為移動賦值運算符重載即可)

類成員變量初始化 (缺省值出自C++11

C++11允許在類定義時給成員變量初始缺省值,默認生成構造函數會使用這些缺省值初始化

強制生成默認函數的關鍵字default:

提供了拷貝構造,就不會生成移動構造了,使用default關鍵字強制生成

Person(Person&& p) = default;

禁止生成默認函數的關鍵字delete:

Person(Person&& p) = delete;

繼承和多態中的final與override關鍵字(出自C++11

可變參數模板

// Args是一個模板參數包,args是一個函數形參參數包
// 聲明一個參數包Args…args,這個參數包中可以包含0到任意個模板參數
//C語言的printf scanf函數的參數就是可變的
//語法不支持使用args[i]這樣方式獲取可變參數

template <class ...Args>
void ShowList(Args... args)
{}

遞歸函數方式展開參數包

// 遞歸終止函數
template <class T>
void ShowList(const T& t)
{cout << t << endl;
}
// 展開函數
template <class T, class ...Args>
void ShowList(T value, Args... args)
{cout << value <<" ";ShowList(args...);
}
int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}

逗號表達式展開參數包

//由于是逗號表達式,在創建數組的過程中會先執行逗號表達式前面的部分printarg(args)
打印出參數
再得到逗號表達式的結果0
//通過初始化列表來初始化一個變長數組, {(printarg(args), 0)…}將會展開成((printarg(arg1),0),
(printarg(arg2),0), (printarg(arg3),0), etc… ),最終會創建一個元素值都為0的數組int arr[sizeof…(Args)]。

template <class T>
void PrintArg(T t)
{cout << t << " ";
}
//展開函數
template <class ...Args>
void ShowList(Args... args)
{int arr[] = { (PrintArg(args), 0)... };cout << endl;
}
int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}

STL容器中的empalce相關接口函數

template <class… Args>
void emplace_back (Args&&… args);

emplace系列的接口,支持模板的可變參數,并且萬能引用。那么相對insert和
emplace系列接口的優勢到底在哪里呢?

int main()
{std::list< std::pair<int, char> > mylist;// emplace_back支持可變參數,拿到構建pair對象的參數后自己去創建對象// 那么在這里我們可以看到除了用法上,和push_back沒什么太大的區別mylist.emplace_back(10, 'a');//避免了臨時對象的創建和拷貝 / 移動,效率更高mylist.emplace_back(make_pair(30, 'c'));//相當于退化為了 push_back() 的效果。//:push_back() 必須先有一個完整的對象(可能是臨時對象),再將其放入容器,比直接構造多一次拷貝 / 移動操作(在優化前)。mylist.push_back(make_pair(40, 'd'));mylist.push_back({ 50, 'e' });//只是用初始化列表簡化了對象的創建,仍會產生臨時對象(調用構造函數)for (auto e : mylist)cout << e.first << ":" << e.second << endl;return 0;
}

lambda表達式

實例

#include <algorithm>
#include <functional>
int main()
{
int array[] = {4,1,8,5,3,7,0,9,2,6};
// 默認升序
std::sort(array, array+sizeof(array)/sizeof(array[0]));
// 降序greater<int>()依賴#include <functional>
std::sort(array, array + sizeof(array) / sizeof(array[0]), greater<int>());
return 0;
}

待排序元素為自定義類型,需要用戶定義排序時的比較規則,仿函數

struct Goods
{string _name;  // 名字double _price; // 價格int _evaluate; // 評價Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};
struct ComparePriceLess
{bool operator()(const Goods& gl, const Goods& gr){return gl._price < gr._price;}
};
struct ComparePriceGreater
{bool operator()(const Goods& gl, const Goods& gr){return gl._price > gr._price;}
};
int main()
{vector<Goods> v = { { "蘋果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠蘿", 1.5, 4 } };sort(v.begin(), v.end(), ComparePriceLess());sort(v.begin(), v.end(), ComparePriceGreater());
}

lambda表達式(匿名函數),其實底層就是仿函數

int main()
{vector<Goods> v = { { "蘋果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 
3 }, { "菠蘿", 1.5, 4 } };sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._price < g2._price; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._price > g2._price; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate < g2._evaluate; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate > g2._evaluate; });
}

lambda表達式語法

實例:
int main()
{// 最簡單的lambda表達式, 該lambda表達式沒有任何意義[]{}; // 省略參數列表和返回值類型,返回值類型由編譯器推導為intint a = 3, b = 4;[=]{return a + 3; }; // 省略了返回值類型,無返回值類型auto fun1 = [&](int c){b = a + c; }; fun1(10)cout<<a<<" "<<b<<endl;// 各部分都很完善的lambda函數auto fun2 = [=, &b](int c)->int{return b += a+ c; }; cout<<fun2(10)<<endl;// 復制捕捉xint x = 10;auto add_x = [x](int a) mutable { x *= 2; return a + x; }; cout << add_x(10) << endl; return 0;
}

lambda表達式實際上可以理解為無名函數,該函數無法直接調用,如果想要直接調用,可借助auto將其賦值給一個變量

lambda表達式書寫格式:[capture-list] (parameters) mutable -> return-type { statement }
  1. [capture-list] : 捕捉列表,編譯器根據[]來判斷接下來的代碼是否為lambda函數,捕捉上下文中的變量供lambda
    函數使用。
  2. (parameters):參數列表。與普通函數的參數列表一致,如果不需要參數傳遞,則可以
    連同()一起省略
  3. mutable:默認情況下,lambda函數總是一個const函數mutable可以取消其常量性。使用該修飾符時,參數列表不可省略(即使參數為空)。
  4. returntype:返回值類型可省略,由編譯器對返回類型進行推導。
  5. {statement}:函數體。在該函數體內,可以使用其參數外,還可使用捕獲
    到的變量。

注意: 在lambda函數定義中,參數列表和返回值類型都是可選部分,而捕捉列表和函數體可以為
空。因此C++11中最簡單的lambda函數為:[]{}; 該lambda函數不能做任何事情

捕獲列表說明

捕捉列表描述了上下文中那些數據可以被lambda使用,以及使用的方式傳值還是傳引用。
[var]:表示值傳遞方式捕捉變量var
[=]:表示值傳遞方式捕獲所有父作用域中的變量**(包括this)**
[&var]:表示引用傳遞捕捉變量var
[&]:表示引用傳遞捕捉所有父作用域中的變量(包括this)
[this]:表示值傳遞方式捕捉當前的this指針

注意:
a. 父作用域指包含lambda函數的語句塊
b. 語法上捕捉列表可由多個捕捉項組成,并以逗號分割。
比如:[=,&a, &b]:以引用傳遞的方式捕捉變量a和b,值傳遞方式捕捉其他所有變量
[&,a,this]:值傳遞方式捕捉變量a和this,引用方式捕捉其他變量
c. 捕捉列表不允許變量重復傳遞,否則就會導致編譯錯誤。
比如:[=, a]:=已經以值傳遞方式捕捉了所有變量,捕捉a重復
d. 在塊作用域以外的lambda函數捕捉列表必須為空
e. 在塊作用域中的lambda函數僅能捕捉父作用域中局部變量,捕捉任何非此作用域或者非局部變量都會導致編譯報錯。
f. lambda表達式之間不能相互賦值,類型不同,其類型構成含有uuid,通用唯一標識符

void (*PF)();
int main()
{auto f1 = []{cout << "hello world" << endl; };auto f2 = []{cout << "hello world" << endl; };//f1 = f2;   //類型不同,不可賦值// 允許使用一個lambda表達式拷貝構造一個新的副本auto f3(f2);//默認包含 operator() 重載(用于調用 Lambda 邏輯)f3();// 可以將lambda表達式賦值給相同類型的函數指針PF = f2;PF();return 0;
}

小結

  1. Lambda 表達式會被編譯器隱式轉換為一個匿名的函數對象類型
  2. 是編譯器自動生成的、唯一的類類型
  3. 默認包含 operator() 重載(用于調用 Lambda 邏輯)
  4. 對于沒有捕獲變量的 Lambda,可隱式轉換為函數指針;有捕獲變量的 Lambda 則不能
函數對象(仿函數)與lambda表達式

函數對象,又稱為仿函數,即可以像函數一樣使用的對象,就是在類中重載了operator()運算符類對象

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;class Rate
{
public:Rate(double rate) : _rate(rate){}double operator()(double money, int year){return money * _rate * year;}
private:double _rate;
};
int main()
{// 函數對象double rate = 0.49;Rate r1(rate);//僅僅調構造cout << r1(10000, 2);//僅僅調operator()cout << endl;// lamber//r1 雖然是外部變量,但未在 Lambda 表達式中使用,因此不會被捕捉auto r2 = [=](double monty, int year)->double {return monty * rate * year; };cout << r2(10000, 2);return 0;
}

函數對象將rate作為其成員變量,在定義對象時給出初始值即可,lambda表達式通過捕獲列表可
以直接將該變量捕獲到。

在這里插入圖片描述

在底層編譯器對于lambda表達式的處理方式,完全就是按照函數對象的方式處理的,
即:如果定義了一個lambda表達式,編譯器會自動生成一個類,在該類中重載了operator()。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98676.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98676.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98676.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

構建Python環境的幾種工具

本文主要介紹如何構建Python環境來處理不同的工作。 1.常用的構建Python環境的工具 ①venv(內置模塊):Python 3.3 內置標準庫模塊&#xff0c;無需額外安裝。 ②virtualenv:venv的前身&#xff0c;功能更強大且支持舊版Python。 ③conda:來自 Anaconda 或 Miniconda。不僅能…

c#項目編譯時外部依賴文件的同步問題

很多場景因為資源文件太多或太大無法放到資源里面或者是依賴的dll文件&#xff0c;需要編譯時同步到bin\debug或bin\release下的&#xff0c;這里面要修改工程文件代碼實現。 比如&#xff0c;我把這個項目依賴的dll和附加文件放到ref_dll文件夾里面&#xff0c;希望編譯的時候…

數學建模常用算法-模擬退火算法

一、模擬退火算法模擬退火的靈感來源于物理中的 “退火過程”—— 將金屬加熱到高溫后&#xff0c;緩慢冷卻&#xff0c;金屬原子會在熱能作用下自由運動&#xff0c;逐漸形成能量最低的穩定結構。算法將這一過程抽象為數學模型&#xff1a;“溫度 T”&#xff1a;對應物理中的…

架構很簡單:業務架構圖

緣起業務架構是一個復雜的體系&#xff0c;如何更簡單的表達&#xff0c;并能使用起來呢&#xff1f;所謂&#xff1a;大道至簡。基于此&#xff0c;這篇文章就開始了。業務是一切架構的開始&#xff0c;如果沒有業務&#xff0c;架構又有什么作用呢&#xff1f;所以做架構首先…

【前端埋點】純前端實現 A/B Test

“純前端實現 A/B Test”&#xff0c;意思就是 沒有后端分流、也不依賴流量網關&#xff0c;那么只能靠前端邏輯來做“流量切分”。 &#x1f3af; 目標 80% 的用戶 → A 頁面20% 的用戶 → B 頁面且要保證 同一個用戶每次訪問結果一致&#xff08;否則用戶刷新頁面時 A/B 會跳…

Day22_【機器學習—集成學習(3)—Boosting—Adaboost算法】

Adaptive Boosting(自適應提升)是基于 Boosting思想實現的一種集成學習算法&#xff0c;核心思想是通過逐步提高那些被前一步分類錯誤的樣本的權重來訓練一個強分類器。一、Adaboost算法直線相當于一個弱學習器&#xff0c;正確的數據權重減小&#xff0c;錯誤的數據權重增加二…

C#語言入門詳解(18)傳值、輸出、引用、數組、具名、可選參數、擴展方法

C#語言入門詳解&#xff08;18&#xff09;傳值、輸出、引用、數組、具名、可選參數、擴展方法一、傳值參數1. 值類型2. 引用類型&#xff0c;并且創建對象3. 引用類型&#xff0c;不創建對象二、引用參數1. 值類型2. 引用類型&#xff0c;創建新對象3. 引用類型&#xff0c;不…

模型部署:(二)安卓端部署Yolov5-v6.0目標檢測項目全流程記錄

模型部署&#xff1a;&#xff08;二&#xff09;安卓端部署Yolov5-v6.0目標檢測項目全流程記錄1、下載NCNN項目2、下載基于安卓的yolov5項目3、修改相應的配置文件4、將項目打包成apk包5、部署自己訓練的yolov5模型6、相關資料下載&#xff1a;1、下載NCNN項目 # 鏈接地址 ht…

圖形基礎算法:如何將點與帶曲線邊的多邊形位置關系算法做穩定

簡介判斷點與多邊形位置關系算法是幾何算法中最基礎的算法之一&#xff0c;包括布爾運算在內的非常非常多的算法都會用到它。它的穩定是算法庫穩定的關鍵。下面我們從一個邊都是直線的多邊形開始了解射線法的原理。然后看看引入曲線后會帶來哪些問題&#xff0c;以及在實際應用…

react的filber架構

好問題 &#x1f44d; 你問的是 React Fiber 架構。這是 React 16 引入的核心機制&#xff0c;用來解決 React 在大規模更新時的性能問題。下面我給你從 背景 → Fiber 是什么 → 原理 → 優點 → 流程 來系統講。一、為什么需要 Fiber&#xff1f;在 React 15 及以前&#xff…

Lucky STUN穿透結合群暉NAS實現docker下transmission監聽端口動態更新

參考文章 LCUKY系列教程 一 「LUCKY STUN穿透」使用 cURL 自動修改 Transmission 的監聽端口 二 「LUCKY STUN穿透」使用 Webhook 自動修改 qbittorrent 的監聽端口 三 LUCKY STUN穿透在Windows上使用UPnP工具為BT客戶端自動添加內外端口號不同的映射規則 四「LUCKY STUN穿透」…

如何在Ubuntu暢玩鳴潮等游戲

本教程只包括Steam上的游戲。# 更新軟件源 sudo apt update # 安裝Steam sudo apt install steam首先&#xff0c;在Ubuntu的snap商店安裝Steam&#xff0c;啟動&#xff0c;登陸&#xff0c;下載游戲。到這里的操作都比較簡單&#xff0c;對于沒有反作弊的游戲&#xff0c;往往…

機器學習09——聚類(聚類性能度量、K均值聚類、層次聚類)

上一章&#xff1a;機器學習08——集成學習 下一章&#xff1a;機器學習10——降維與度量學習 機器學習實戰項目&#xff1a;【從 0 到 1 落地】機器學習實操項目目錄&#xff1a;覆蓋入門到進階&#xff0c;大學生就業 / 競賽必備 文章目錄一、聚類任務&#xff08;無監督學習…

解決 Docker 構建中 Python 依賴沖突的完整指南

問題背景 在基于 registry.cn-shenzhen.aliyuncs.com/all_dev/dev:invoice-base 鏡像構建 Docker 容器時,我們遇到了一個常見的 Python 依賴管理問題: ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-…

光子計算芯片實戰:Lightmatter Passage互連架構性能評測

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 摘要 隨著人工智能計算需求呈指數級增長&#xff0c;傳統電子計算…

基于樹莓派與Jetson Nano集群的實驗邊緣設備上視覺語言模型(VLMs)的性能評估與實踐探索

概述 2018年&#xff0c;TensorFlow Lite團隊的Pete Warden曾提出&#xff1a;“機器學習的未來在于微型化”。如今&#xff0c;隨著人工智能向高性能視覺強大的視覺語言模型&#xff08;Vision-language models, VLMs&#xff09;發展&#xff0c;對高性能計算資源的需求急劇…

華為Ai崗機考20250903完整真題

華為Ai崗機考20250903 華為自26屆秋招&#xff08;2025年起&#xff09;對AI崗位機考進行了改革&#xff0c;考試題型調整為20道選擇題&#xff08;15道單選(6分)5道不定項選擇(12分)&#xff09;2道編程題(150300)。 題目核心圍繞人工智能技術&#xff08;如Transformer架構…

k8s+jenkins+harbor構建Devops平臺

一、環境準備1、準備一主一從k8s機器&#xff0c;&#xff08;設備好可以一主多從也行&#xff09;2、一臺harbor倉庫機器&#xff08;dockerhub訪問不了&#xff09;二、安裝nfs服務1、在k8s機器上yum install nfs-utils -y systemctl start nfs systemctl enable nfs2、創建共…

為什么 socket.io 客戶端在瀏覽器能連上,但在 Node.js 中報錯 transport close?

網羅開發&#xff08;小紅書、快手、視頻號同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企業從事人工智能項目研發管理工作&#xff0c;平時熱衷于分享各種編程領域的軟硬技能知識以及前沿技術&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

人才教育導向下:老年生活照護實訓室助力提升學生老年照護服務能力

一、老年生活照護實訓室建設背景與意義 &#xff08;一&#xff09;適應老齡化社會需求 我國老齡化程度持續加深&#xff0c;老年照護服務人才缺口不斷擴大。培養專業照護人才成為當務之急&#xff0c;職業教育需承擔重要責任。點擊獲取實訓室建設方案 &#xff08;二&…