C++11的內容

1.支持花括號初始化

void test1()
{vector<string> v1 = { "asd","asd","add" };vector<string> v2{ "asd","asd","add" };map<string, int> m1={ {"asd",1},{"asd",2},{"asd",3} };map<string, int> m2{ {"asd",1},{"asd",2},{"asd",3} };}

當編譯器遇到花括號初始化表達式時,會發生以下的步驟:

template<class T>
class F
{
public:F(std::initializer_list<T> il) {};     //  如果該構造函數存在直接就調用F() {};
};

步驟 1:

優先匹配 std::initializer_list 構造函數 如果類型 F定義了 接受 std::initializer_list的構造函數 (如 F(std::initializer_list<U>)),編譯器會優先嘗試調用它。 此時,花括號內的所有參數會被打包成一個 std::initializer_list<T>臨時對象,其中 T 是花括號內元素的統一類型(需支持隱式轉換)。

步驟2:

?如果 initializer_list構造函數不匹配(如參數類型無法轉換,或未定義該構造函數),編譯器會按常規構造函數重載決議規則選擇其他構造函數。 花括號內的參數會逐個傳遞給構造函數,如同圓括號初始化。

步驟3:

聚合類型的直接初始化 如果T是聚合類型(如沒有用戶自定義構造函數的結構體、數組等),花括號會按聲明順序直接初始化成員。

template<class T>
class F
{
public://F(std::initializer_list<T> il) {};     //  如果該構造函數存在直接就調用//F() {};int _a;double _b;
};void test()
{F<int> f{ 1,1.0 };  // 按聲明順序初始化
}

注意:

1.窄化轉換的檢查 無論調用哪種構造函數,花括號初始化都會靜態檢查窄化轉換(如 double→int),若存在則編譯失敗。

template<class T>
class F
{
public://F(std::initializer_list<T> il) {};     //  如果該構造函數存在直接就調用//F() {};int _a;double _b;
};void test()
{F<int> f{ 1.1,1.0 };  // 按聲明順序初始化  // double->int 本應該發生窄化報錯,但發生了自定義類型的隱式類型的轉化int x{ 1.5 };  //  編譯時報錯
}

2.當默認構造函數和initlalizer_list都存在時,花括號里面非空,調用initializer_list,空就調默認構造函數。

3.模板函數需要顯示參數類型。

template<typename T>
void foo(T param) {}void test0()
{//foo({ 1, 2 });  // 錯誤:無法推導 T(必須顯式指定為 std::initializer_list<int>)foo(initializer_list<int>{1, 2});
}

2.decltype自動推導類型

void test2()
{int a = 1;double b = 2.0;auto c = a + b;           //  auto不能作形參和返回值cout << typeid(c).name() << endl;    //  doublestring s;decltype(c) d;cout << typeid(d).name() << endl;     //  doubledecltype(s) e;cout << typeid(e).name() << endl;      //class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
}

3.final 和override

?final 修飾類,類就變成了最終類,不能被繼承,修飾虛函數,該虛函數不能被重寫。? ? ? ? ? ? override 檢查子類是否重寫虛函數。

4.?顯示調用默認構造函數

class A
{
public:A() = default;   //指定顯示去生成默認構造函數,因為當自己寫了構造函數,就不會默認生成,但如果傳參不匹配,無法構造,又不能調用默認構造函數,會報錯,所以顯示調用。A(const int& a):_a(a){ }private:int _a = 20;
};void test3()
{A a;  //  當沒有A() = default,會報錯 
}

5.禁止拷貝

class B
{
private://  B(const B& b);  //  C++98 只聲明,不實現,別人就無法拷貝對象,為了防止在類外定義,用private限定//  在C++11中定義了新的語法禁止拷貝B(const B& b)= delete;B& operator=(const B& b) = delete;
};

6.右值引用

void test5()
{// 左值通常都是變量// 右值通常都是常量(表達式或者函數返回的值)int a = 0;int& b = a;   // 左值引用 引用左值// 如果用 左值引用 引用右值要加constconst int& c = 0;// 右值引用 引用右值int&& d = 1;        // 節省空間int e = 1;    //  直接賦值和右值引用的區別,右值引用不需要開辟空間,拷貝對象// 右值引用 引用左值要加movecout << "e的類型:" << typeid(e).name() << endl;int&& f = move(e);     // f與e的地址一樣。cout << "e的類型:" << typeid(e).name() << endl;auto f1 = move(e);e = 3;cout <<"e:"<< e << "  " <<"f:"<< f << endl;f = 2;cout <<"e:"<<e << "  " <<"f:"<< f << endl;//  右值引用的是常量,為什么f能改變呢?并且將e改變了int&& g = 1 + 2;int& h = g;  //  雖然不能對常量用& 但可以對g用&cout << "&h:" << &h << endl;cout << "&g:" << &g << endl;h = 5;cout << "g:" << g << "  " << "h:" << h << endl;//  可以通過h改變g}

move對對像本身沒什么影響,將對象標記為可以移動的,可以調用vector或string的移動構造函數,但移動構造函數將原來對象對這片內存的權限取消了,給了新的對象,將原來的對象置空或0。
其實,右值引用的作用主要發揮在調用移動構造,只轉移管理權,不開辟空間,減少了內存的開銷。(前提是,如果要調用移動構造,move的對象你不再使用了),對于一般的,如上面的move的使用,與左值引用無異。

7.lambda表達式

格式:?[捕捉列表](形參)->返回類型{函數體}

void test8()
{auto r3 = [](int x) {return x; };     // r3 is a name of lambdacout << typeid(r3).name() << endl;int a = 1;int b = 2;int y = 3;int x = 0;cout << "a:" << a << " " << "b:" << b << endl;auto r1=[&a, &b](int x, int y)->int{a++; b++; return x + y; };  //  [捕捉列表](形參)->返回類型{函數體}int ret=r1(x, y);cout << "a:" << a << " " << "b:" << b << "  " << "ret:" << ret << endl;// 不作列表只能捕捉同一作用域變量//傳值捕捉的對象不能改變(值的大小)//auto rr = [a, b]() {//	int tmp = a;//	a = b;//	b = tmp;//	}     //  報錯auto rr = [a, b]()mutable {int tmp = a; //  (改變了值的大小)a = b;b = tmp;     //  加mutable就可以了,但沒意義,用引用捕獲就行};// 用途vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };int num = count_if(v.begin(), v.end(), [](int n) {return n % 3==0; }); //  num 大小為返回true的個數  //  count_if 返回滿足條件的范圍中的元素數cout <<"滿足條件個數:"<< num << endl;//  for_each  將函數應用于范圍for_each(v.begin(), v.end(), [](int& v) {cout << v << " "; });}結果:
class `void __cdecl test8(void)'::`2'::<lambda_1>
a:1 b:2
a:2 b:3  ret:3
滿足條件個數:3
1 2 3 4 5 6 7 8 9 10

《C++ primer》解釋

8.引用折疊與完美轉發

核心規則: 只要有一個 &(左值引用),最終結果就是 T&(左值引用)。 只有全是 &&右值引用),最終結果才是 T&&(右值引用)。

template<class T>
void B1(T&& t) { cout << "void B(T&& t)" << endl; };
template<class T>
void B1(T& t) { cout << "void B(T& t)" << endl; };
template<class T>
void B1(const T&& t) { cout << "void B(const T&& t)" << endl; };
template<class T>
void B1(const T& t) { cout << "void B(const T& t)" << endl; };template<class T>
void A1(T&& t)     //第一次引用折疊
{//右值引用在第二次傳參后,屬性丟失//完美轉發解決B1(t);//B1(std::forward<T>(t)); // 調用forward 發生第二次引用折疊
}void test9()
{int a = 1;const int b = 2;A1(a);           A1(b);       A1(move(a));   A1(move(b));  // 只有左值引用會引發引用折疊// int&& c = move(b);   //  不允許直接move有const修飾的對象const int&& c = move(b);// int&& c = move(const_cast<int>(b)); // 用const_cast,是const修飾的變量指向的數據是可以修改的,2是一個常量}結果:
void B(T& t)
void B(const T& t)
void B(T& t)
void B(const T& t)
可以看出在第二次傳參時,值的屬性消失
B1(std::forward<T>(t)); // 調用forward 發生引用折疊結果:
void B(T& t)
void B(const T& t)
void B(T&& t)
void B(const T&& t)屬性沒有丟失

根據折疊規則:

forward函數:

emplate<typename T>
T&& forward(std::remove_reference_t<T>& t) noexcept {return static_cast<T&&>(t);  // 引用折疊發生在這里
}

根據折疊規則:

如果 T是 int&: static_cast<int& &&>(t) → static_cast<int&>(t)(保持左值)。

如果 T是 int: static_cast<int&&>(t)(保持右值)。

forward很巧妙的使用了折疊的規則:

如果沒有forward折疊,那么下面兩種 int ,const int會被推導為int&,const int&

因:第一次折疊搗的鬼。

果:forward巧妙的借用了折疊鬼完成完美轉發。

師夷長技以制夷。

在 A1(move(a)) 的場景中,雖然 A1()函數中的t 的類型已經是 int&&(右值引用),直接傳遞 t 似乎也能保留右值屬性,但使用 std::forward 仍然必要

?直接傳遞 t 的問題 :右值引用變量 t是左值表達式,在 A1函數內部,t 是一個具名變量(即使它的類型是 int&&),而所有具名變量都是左值表達式。?

9.線程

int x = 0;
void Add2(int num)
{for (int i = 0; i < num; i++){++x;}
}void test10()
{thread t1(Add2, 1000000);thread t2(Add2, 1000000);t1.join();t2.join();     //  t1和t1 同時進行線程,對x加10000000次,會有沖突cout << "x:" << x << endl;   //  x<2000000}
不同的線程對同一個對象進行處理,會發生同時拿這個對象,同時加1,x只加一次結果(多次):
x:1044214
x:1052133
x:1187482

9.1鎖的使用

mutex mtx;   // 不能將互斥鎖放在Add3()里,不然每個線程創建自己的互斥鎖
void Add3(int num)
{mtx.lock();for (int i = 0; i < num; i++){++m;}mtx.unlock();
}   // 串行void test10()
{// 互斥鎖thread t3(Add3, 1000000);thread t4(Add3, 1000000);t3.join();t4.join();    cout << "m:" << m << endl;  }結果:
m:2000000

9.2原子

void test11()
{atomic<int> x2 = 0;auto Add5 = [&x2](int num) {for (int i = 0; i < num; i++){++x2;}};thread t1(Add5, 1000000);thread t2(Add5, 1000000);cout << t1.get_id() << endl;cout << t2.get_id() << endl;t1.join();t2.join();  cout << "x:" << x2 << endl;    // 原子不上鎖,也準確。}

原子不會有沖突。

9.3條件變量

成員


雙線程打印1~100,一個線程打印奇數,另一個線程打印偶數

void test13()
{int num = 100;condition_variable cv1;condition_variable cv2;mutex m1;mutex m2;thread t1([&]() {for (int i = 0; i < num; i += 2){if (i)    // 第一次不鎖{unique_lock<mutex>lock1(m1);cv1.wait(lock1);}cout << this_thread::get_id() << ":" << i << endl;cv2.notify_one();}});thread t2([&]{for (int i = 1; i < num; i += 2){unique_lock<mutex>lock2(m2);cv2.wait(lock2);cout << this_thread::get_id() << ":" << i << endl;cv1.notify_one();}});t1.join();t2.join();}

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

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

相關文章

AI代碼助手實踐指南

概述與發展趨勢 核心理念 發展方向&#xff1a;從代碼補全 → 代碼生成 → 整個工程服務價值轉換&#xff1a;從單純寫代碼 → 需求驅動的代碼生成功能擴展&#xff1a;超越編寫層面&#xff0c;涵蓋測試環境搭建等 核心價值點 低價值動作識別&#xff1a;debug、代碼評審、…

.net反編譯工具

.NET 反編譯工具大揭秘 在.NET 開發的世界里&#xff0c;有時候我們需要對已編譯的.NET 程序集進行反編譯&#xff0c;將 DLL 或 EXE 文件還原為可讀的源代碼形式&#xff0c;這在學習、調試、代碼分析等方面都有著重要的作用。今天&#xff0c;就讓我們一起深入了解一些流行的…

mac docker desktop 安裝 oracle

1.登錄 oracle 官網&#xff0c;選擇鏡像 https://container-registry.oracle.com/ords/f?p113:1:6104693702564::::FSP_LANGUAGE_PREFERENCE:&cs3CAuGEkeY6APmlAELFJ0uYU5M8_O8aTEufSKZHFf12lu1sUk5fsdbCzJAni9jVaCYXf-SNM_8e3VYr1V4QMBq1A 2.登錄認證 oracle 賬號 doc…

【redis使用場景——緩存——數據過期策略 】

redis使用場景——緩存——數據過期策略 定期刪除&#xff08;Active Expiration&#xff09;1. 快速模式&#xff08;Fast Expiration Cycle&#xff09;工作流程&#xff1a;特點&#xff1a;優點&#xff1a; 2. 慢速模式&#xff08;Slow Expiration Cycle&#xff09;工作…

智能體Manus和實在Agent的區別

在當今數字化時代&#xff0c;AI 已經深度融入我們的生活和工作。曾經&#xff0c;像 ChatGPT 這樣的傳統 AI&#xff0c;雖然能在很多方面給我們提供幫助&#xff0c;比如寫郵件時它妙筆生花&#xff0c;分析數據時頭頭是道&#xff0c;可卻在最后一步掉了鏈子 —— 它不會點擊…

Prism框架實戰:WPF企業級開發全解

以下是一個完整的WPF項目示例&#xff0c;使用Prism框架實現依賴注入、導航、復合命令、模塊化和聚合事件功能。項目結構清晰&#xff0c;包含核心功能實現&#xff1a; 項目結構 PrismDemoApp/ ├── PrismDemoApp (主項目) │ ├── Views/ │ │ ├── ShellView…

單片機學習筆記---AD/DA工作原理(含運算放大器的工作原理)

目錄 AD/DA介紹 硬件電路模型 硬件電路 運算放大器 DA原理 T型電阻網絡DA轉換器 PWM型DA轉換器 AD原理 逐次逼近型AD轉換器 AD/DA性能指標 XPT2046 XPT2046時序 AD/DA介紹 AD&#xff08;Analog to Digital&#xff09;&#xff1a;模擬-數字轉換&#xff0c;將模擬…

matlab實現相控超聲波成像

相控超聲波成像仿真檢測探傷 數據接收 換能器開發 Phased Array Codes/Matlab Examples.pptx , 513230 Phased Array Codes/MATLAB M_files/delay_laws2D.m , 1027 Phased Array Codes/MATLAB M_files/delay_laws2D_int.m , 3290 Phased Array Codes/MATLAB M_files/delay_law…

Stable Diffusion入門-ControlNet 深入理解 第二課:ControlNet模型揭秘與使用技巧

大家好&#xff0c;歡迎回到Stable Diffusion入門-ControlNet 深入理解系列的第二課&#xff01; 如果你還記得第一篇文章的內容 - 我們已經了解了 ControlNet 的基礎概念&#xff1a;它通過預處理器和模型兩個強力模塊&#xff0c;賦予了AI繪畫前所未有的精準控制。 還沒看過…

大數據時代UI前端的變革:從靜態展示到動態交互

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 在大數據時代&#xff0c;信息以前所未有的速度和規模增長。這種數據環境的變化&#xff0c;深…

引腳個數、引腳寬度、引腳之間距離

原圖&#xff1a; 最終效果圖如下&#xff1a; 1.讀取圖片并設置參數 read_image (Image, ic_pin) dev_set_draw (margin) dev_set_line_width (2) dev_get_window (WindowHandle) get_image_size (Image, Width, Height) 2.繪制提取的ROI區域 r:58 // 旋轉矩形的中心點坐標…

內網和外網有什么區別?如何將內網ip端口地址映射到外網用?

由于局域網的使用&#xff0c;區分出了內網和外網兩種概念。以路由器為核心&#xff0c;可以將多臺電腦組建成一個局域網&#xff0c;局域網之內的網絡便是內網。內網是有距離限制的&#xff0c;只有在路由器信號范圍內的電腦才能接入局域網&#xff0c;否則需要進行內網穿透技…

Git倉庫的原理理解

國內外主流的 Git 代碼托管平臺 (持續更新) - JetsungChan - 博客園 .gitignore文件講解( 忽略規則文件 )[重點] (主要目的是為了節省空間 , 不必要的文件不要管他 , 忽略掉) 重復文件的云儲存(只會上傳一份) (所以不要怕stm32每個工程文件 , 有幾十M , 全部上傳會太大 . 實際…

011 Linux進程

&#x1f984; 個人主頁: 小米里的大麥-CSDN博客 &#x1f38f; 所屬專欄: Linux_小米里的大麥的博客-CSDN博客 &#x1f381; GitHub主頁: 小米里的大麥的 GitHub ?? 操作環境: Visual Studio 2022 文章目錄 深入理解 Linux 進程管理一、管理哲學/本質&#xff1a;先描述&am…

星型模型(Star Schema)

在數據倉庫的體系概念中&#xff0c;星型模型&#xff08;Star Schema&#xff09;和雪花模型&#xff08;Snowflake Schema&#xff09;是兩種常見的數據模型&#xff0c;用于組織和結構化數據&#xff0c;以支持高效的查詢和分析。 今天我們先介紹星型模型&#xff08;Star …

【RAG面試題】如何獲取準確的語義表示

目錄 回答模板 語義表示是干什么的&#xff1f; 如何獲取準確語義表示的關鍵步驟&#xff1f; 1. 選擇合適的 Embedding 模型 2. 正確的文本預處理與切分 3. 文本清洗與標準化 4. 構建合理的向量庫 5. 檢索質量驗證與優化 詳細知識點覆蓋 面試回答技巧 回答模板…

小程序 API 開發手冊:從入門到高級應用一網打盡

在移動互聯網浪潮中&#xff0c;小程序已經成為企業服務用戶的“第二戰場”。不論是微信小程序、支付寶小程序&#xff0c;還是抖音小程序&#xff0c;都在強調一個核心能力&#xff1a;快速響應用戶需求。而支撐小程序靈活運行和豐富功能的關鍵技術之一&#xff0c;正是小程序…

iwebsec靶場sqli注入(2)

??????06-寬字節注入 1&#xff0c;該漏洞的根本原因是字符集處理不一致&#xff08;GBK雙字節特性&#xff09;與不安全的轉義方式&#xff08;addslashes&#xff09;共同導致。構造基礎sql注入語句 1%df%27%20%23 漏洞原理 字符集設置&#xff1a;mysql_query("S…

小程序學習筆記:自定義組件創建、引用、應用場景及與頁面的區別

在微信小程序開發中&#xff0c;自定義組件是一項極為實用的功能&#xff0c;它能有效提高代碼的復用性&#xff0c;降低開發成本&#xff0c;提升開發效率。本文將深入剖析微信小程序自定義組件的各個關鍵方面&#xff0c;包括創建、引用、應用場景以及與頁面的區別&#xff0…

開發數字化綠色低碳園區系統:分階段實施指南

目錄 摘要 背景 核心模塊 階段性開發 分階段開發實施 第一階段(3-6個月):搭建核心骨架 第二階段(6-9個月):擴展功能 第三階段(9-12個月):深度定制 技術選型 注意事項 實施計劃表 小結 摘要 數字化綠色低碳園區系統通過物聯網、能源管理和數據分析等技術,…