c++11新特性隨筆

1.統一初始化特性

c98中不支持花括號進行初始化,編譯時會報錯,在11當中初始化可以通過{}括號進行統一初始化。

c98編譯報錯

c++11:?

#include <iostream>
#include <set>
#include <string>
#include <vector>int main()
{std::string str = {"111"};std::vector<std::string> vec = {"aaa","bbb","cc"};std::cout<<"str = "<<str.c_str()<<std::endl;for(auto it : vec){std::cout<<"it = "<<it.c_str()<<std::endl;}return 0;
}

輸出:

root@ubuntu:~/mySpace/other/ERT# ./a.out 
str = 111
it = aaa
it = bbb
it = cc
root@ubuntu:~/mySpace/other/ERT# 

2.關鍵提auto自動推導變量類型

#include <iostream>
#include <set>
#include <string>
#include <vector>
#include <map>int main()
{std::vector<std::string> vec = {"aaa","bbb","cc"};//// 直接根據實際情況推導相關變量類型for(auto it : vec){std::cout<<"it = "<<it.c_str()<<std::endl;}std::map<std::string,std::string> m = {{"11","111"},{"33","333"}};for(auto &it : m){std::cout<<"first = "<<it.first.c_str()<<" "<<"second = "<<it.second.c_str()<<std::endl;}for(auto it = m.begin();it !=m.end();++it){std::cout<<"first = "<<it->first.c_str()<<" "<<"second = "<<it->second.c_str()<<std::endl;}//c++17.c++11不支持該屬性// for (const auto& [key, value] : myMap) {//     std::cout << "Key: " << key << ", Value: " << value << std::endl;// }return 0;
}

?輸出:

root@ubuntu:~/mySpace/other/ERT# ./a.out 
it = aaa
it = bbb
it = cc
first = 11 second = 111
first = 33 second = 333
first = 11 second = 111
first = 33 second = 333
root@ubuntu:~/mySpace/other/ERT#

3.Lambda表達式

????????定義匿名函數對象,常用于簡化代碼,尤其是在需要傳遞函數作為參數的場景。在編譯器編譯過程中會將lambda表達式轉化成一個匿名類,并且這個匿名類重載了operator()運算符,使得可以像函數一樣被調用(類的仿制函數一樣)。

????????lamda表達式函數會自動推倒返回值無需編寫,帶返回值的寫法,如下:

語法結構表達:

    // lamda表達式函數會自動推到返回值無需編寫,帶返回值的寫法auto pFunRet = []() -> std::string {std::string s("rrrrr");return s;}; std::cout<<"pFunRet() = "<<pFunRet().c_str()<<std::endl;

a.無參表達

 // 無參Lamda函數表達式auto pFun = [](){std::cout<<"This is lamda fun"<<std::endl;};pFun();

輸出:

root@ubuntu:~/mySpace/other/ERT# ./a.out 
This is lamda fun
root@ubuntu:~/mySpace/other/ERT#

如上表示無參數表達式,編譯器會將上述函數轉化成一個匿名累,如下,將函數轉化成匿名類,直接像函數一樣調用即可。

class __lambda_anonymous {
public:int operator()() const { std::cout<<"This is lamda fun"<<std::endl; }
};

b.有參數表達

   // 帶參數auto pFunParams = [](int a,std::string s){std::cout<<"Params lamda="<<a<<"-"<<s.c_str()<<std::endl;};pFunParams(100,"LX");

輸出:? ?

root@ubuntu:~/mySpace/other/ERT# ./a.out 
Params lamda=100-LX
root@ubuntu:~/mySpace/other/ERT#

?轉化匿名類形式:

class __lambda_anonymous {
public:int operator()(int a,std::string s) const { std::cout<<"Params lamda="<<a<<"-"<<s.c_str()<<std::endl; }
};

c.值捕獲

????????(值捕獲,捕獲作用域所有值,=可以替換成某個具體的值,表示單個變量捕獲)

  // 值捕獲,捕獲作用域所有值,=可以替換成某個具體的值,表示單個變量捕獲int val_0 = 1;int val_2 = 2;auto pFunValue = [=](){// 值捕獲都是只讀權限,強行改變會編譯報錯,提醒read-only 'val_0'// val_0 += 1;// val_2 += 2;std::cout<<"val_0="<<val_0<<" val_2="<<val_2<<std::endl;};pFunValue();

輸出:?

root@ubuntu:~/mySpace/other/ERT# ./a.out 
val_0=1 val_2=2
root@ubuntu:~/mySpace/other/ERT#

??編譯器轉化:

class __lambda_anonymous {
private:int val_0 = 1;int val_2 = 2;
public:__lambda_anonymous(int val_0,int val_2) : val_0(val_0),val_2(val_0) {}  // 構造函數int operator()() const { std::cout<<"val_0="<<val_0<<" val_2="<<val_2<<std::endl;; }
};

d.mutble關鍵字

????????通過該關鍵字修飾等價于函數內部做了一份拷貝,之后再對拷貝進行操作,故而可以修改其捕獲value2,?

   // 值捕獲2int value2 = 100;std::cout<<"before modify value2="<<value2<<std::endl;auto pFunValue2 = [value2]() mutable { // mutable 修飾等價于函數內部做了一份拷貝,之后再對拷貝進行操作,故而可以修改其捕獲value2,如下輸出結果展示:// before modify value2=100// value2=211// after modify value2=100value2 += 111;std::cout<<"value2="<<value2<<std::endl;};pFunValue2();std::cout<<"after modify value2="<<value2<<std::endl;

輸出:

root@ubuntu:~/mySpace/other/ERT# ./a.out 
before modify value2=100
value2=211
after modify value2=100
root@ubuntu:~/mySpace/other/ERT#

編譯器匿名類:

class __lambda_unnamed {int value2 ;
public:__lambda_unnamed(int value2 ) : value2 (value2 ) {}int operator()(int value2) {  // 注意:不再是constvalue2 += 111;std::cout<<"value2="<<value2<<std::endl;}
};

e.引用捕獲

????????引用修改的是捕獲的變量的本身,如下:

  // 引用捕獲int quote = 100;std::cout<<"before modify quote="<<quote<<std::endl;auto pFunQuote = [&quote](){quote += 20; // 引用修改的是捕獲的變量的本身,如下輸出結果://before modify quote=100//quote=120//after modify quote=120std::cout<<"quote="<<quote<<std::endl;};pFunQuote();std::cout<<"after modify quote="<<quote<<std::endl;return 0;

輸出:? ?

root@ubuntu:~/mySpace/other/ERT# ./a.out 
before modify value2=100
value2=211
after modify value2=100
root@ubuntu:~/mySpace/other/ERT# 

?編譯器轉換:

class __lambda_anonymous {
private:int quote;  // 值捕獲的成員變量
public:__lambda_anonymous(int quote) : quote(quote) {}  // 構造函數int operator()(int quote) const { quote += 1;std::cout<<"quote="<<quote<<std::endl;; }
};

4.并發編程

? ?a.創建線程:

#include <iostream>
#include <thread>void hello() {std::cout << "Hello from thread!\n";
}int main() {std::thread t(hello);  // 創建線程并啟動t.join();              // 等待線程結束// 分離線程,線程結束后自動釋放資源// 注意:分離后不能再join()// t.detach();  return 0;
}

? ?b.帶參數線程處理函數

#include <iostream>
#include <thread>
void print(int id, const std::string& name) {std::cout << "ID: " << id << ", Name: " << name << "\n";
}int main() {std::thread t(print, 1, "Thread1");t.join();return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
ID: 1, Name: Thread1
root@ubuntu:~/mySpace/other/ERT#

? ?c.參數引用傳遞

#include <iostream>
#include <thread>
void modify(int& x) { x *= 2; 
}int main() {int x = 10;std::thread t(modify, std::ref(x));t.join();std::cout << x <<std::endl;  // 輸出20return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
20
root@ubuntu:~/mySpace/other/ERT# 

? ?d.線程id和當前線程

#include <iostream>
#include <thread>int main() {std::thread::id main_thread_id = std::this_thread::get_id(); // 當前線程std::thread t([&]() {if (std::this_thread::get_id() == main_thread_id) {std::cout << "This is the master thread\n";} else {std::cout << "This is a son thread\n";}});t.join();return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
This is a son thread
root@ubuntu:~/mySpace/other/ERT# 

e.互斥鎖?

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_data = 0;void increment() {mtx.lock();std::thread::id current_id = std::this_thread::get_id();std::cout<<"current id = "<<current_id<<std::endl;++shared_data;mtx.unlock();
}// 更安全的方式:使用RAII鎖
void safe_increment() {// 離開作用域時自動解鎖std::lock_guard<std::mutex> lock(mtx);++shared_data;
}int main() {std::thread::id main_thread_id = std::this_thread::get_id(); // 當前線程std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout<<"shared_date ="<<shared_data<<std::endl;return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
current id = 140137569199872
current id = 140137560807168
shared_date =2
root@ubuntu:~/mySpace/other/ERT#

f.原子操作

#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++i) {++counter;  // 原子操作,無需額外同步}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << counter<<std::endl;  // 總是2000return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
2000
root@ubuntu:~/mySpace/other/ERT#

g.異步操作

? ? ? ? 字段(Future/Promise/Async)?std::futurestd::promise?和?std::async?來簡化異步編程,它們共同構成了 C++ 的?并發編程模型,用于處理多線程任務和異步操作

std::async?簡化異步任務的啟動

#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <future>int compute() {// 模擬耗時計算std::this_thread::sleep_for(std::chrono::seconds(1));return 42;
}void fun(){std::cout<<"This fun"<<std::endl;
}
int main() {std::future<int> result = std::async(std::launch::async, compute);// 可以做其他工作創建一個線程運行std::thread t(fun);t.join();std::cout << "Result: " << result.get() << "\n";  // 阻塞直到結果就緒return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
This fun
Result: 42
root@ubuntu:~/mySpace/other/ERT#

?std::future: 用于獲取異步計算的結果(阻塞等待)-未來值

  • 功能:表示一個?異步計算的結果(可能在另一個線程中計算)。

  • 特點

    • 通過?get()?獲取結果(如果結果未就緒,會阻塞當前線程直到計算完成)。

    • 只能獲取一次結果(第二次調用?get()?拋出異常)。

    • 通過?wait()?等待結果就緒(不獲取值)。

  • 適用場景:獲取異步任務(如?std::async?或?std::promise)的返回值?

? ? ? ? 案例:

#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <future>int compute() {std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "during: " << 2 << std::endl;return 42;  // 模擬耗時計算
}int main() {std::future<int> fut = std::async(std::launch::async, compute);// 異步啟動一個任務std::cout << "Waiting for result..." << std::endl;int result = fut.get();  // 阻塞直到 compute() 完成std::cout << "Result: " << result << std::endl;return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
Waiting for result...
during: 2
Result: 42
root@ubuntu:~/mySpace/other/ERT# 

?std::promise:?用于線程間傳遞數據(生產者-消費者模式)

  • 功能:用于?在線程間傳遞數據,允許一個線程設置值,另一個線程通過?std::future?獲取該值。

  • 特點

    • promise.set_value()?設置值,并通知?future?可以獲取。

    • 如果?promise?被銷毀但未設置值,future.get()?會拋出?std::future_error

  • 適用場景:線程間通信,特別是當一個線程需要等待另一個線程的計算結果時。

案例:

????????

#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <future>void compute(std::promise<int> prom) {prom.set_value(42);  // 設置值
}int main() {// 創建promise對象std::promise<int> prom;// 通過future獲取值std::future<int> fut = prom.get_future(); // 通過移動給prom賦值std::thread t(compute, std::move(prom));  // 傳遞 promise// 阻塞直到 compute() 設置值int result = fut.get();  std::cout << "Result: " << result << std::endl;t.join();return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out 
Result: 42
root@ubuntu:~/mySpace/other/ERT# 

8. 線程局部存儲?

? ? ? ? a.局部全局變量

????????thread_local int tls_var = 0; ??每個線程都有自己的 tls_var

#include <iostream>
#include <thread>// 每個線程都有自己的 tls_var,跟linux系統中__thread關鍵類似,多線程中,每個線程都獨有一份全局變量。
thread_local int tls_var = 0;  void increment() {tls_var++;  // 修改的是當前線程的副本std::cout << "Thread " << std::this_thread::get_id() << ": tls_var = " << tls_var << std::endl;
}int main() {std::thread t1(increment);  // t1 的 tls_var 初始為 0,執行后變為 1std::thread t2(increment);  // t2 的 tls_var 初始為 0,執行后變為 1t1.join();t2.join();return 0;
}

? ? ? ? b.類的靜態線程局部變量

????????

#include <iostream>
#include <thread>class Counter {
public:// 每個線程有自己的 countstatic thread_local int count;  void increment() {count++;std::cout << "Thread " << std::this_thread::get_id() << ": count = " << count << std::endl;}
};// 靜態成員類外初始化
thread_local int Counter::count = 0;  int main() {Counter c;// t1 的 count 初始 0 → 1std::thread t1([&c]() {c.increment(); });  // t2 的 count 初始 0 → 1std::thread t2([&c]() { c.increment(); }); t1.join();t2.join();return 0;
}輸出:每個線程都獨享一份變量count
root@ubuntu:~/mySpace/other/ERT# ./a.out 
Thread 140491193476864: count = 1
Thread 140491185084160: count = 1
root@ubuntu:~/mySpace/other/ERT#

以上就是c++11新特性總結筆記,可能還未完全,后續繼續完善!歡迎學習指點!共同進步!!!

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

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

相關文章

Spark-Streaming簡介 核心編程

1. Spark-Streaming概述 定義&#xff1a;用于處理流式數據&#xff0c;支持多種數據輸入源&#xff0c;可運用Spark原語運算&#xff0c;結果能保存于多處。它以離散化流&#xff08;DStream&#xff09;為抽象表示&#xff0c;是RDD在實時數據處理場景的封裝。 特點&#x…

SpringbootWeb開發(注解和依賴配置)

Lombok 工具 Spring Web web開發相關依賴 MyBatis Framework MyBatis驅動 MySQL Driver MySql驅動包 Restful 風格 Slf4j 記錄日志對象 RequestMapping(value “/depts”, method RequestMethod.GET) //指定請求方式為GET method 指定請求方式 GetMapping 限定請求方式為Get…

雜項知識點

雜項 1 激活函數1.1 sigmoid1.2 tanh1.3 Relu1.4 leakRelu 1 激活函數 常用的激活函數包括sigmoid tanh Relu leakRelu 1.1 sigmoid import torch import numpy as np import matplotlib.pyplot as plt # sigmoid tanh Relu leakRelu ## 1 sigmoid ### 1.1 代碼復現sig…

計算機組成原理:指令系統

計算機組成原理:指令集系統 指令集體系結構(ISA)ISA定義ISA包含的內容舉個栗子指令的基本組成(操作碼+地址碼)指令分類:地址碼的個數定長操作碼變長操作碼變長操作碼的原則變長操作碼的設計指令尋址尋址方式的目的尋址方式分類有效地址直接在指令中給出有效地址間接給出有效地…

Rust實現高性能目錄掃描工具ll的技術解析

Rust實現高性能目錄掃描工具ll的技術解析 一、項目概述 本項目使用Rust構建了一個類ls命令行工具&#xff0c;具備以下核心特性&#xff1a; 多格式文件信息展示并行目錄掃描加速人類可讀文件大小運行時性能統計交互式進度提示 二、技術架構 1. 關鍵技術棧 clap&#xff…

【深度強化學習 DRL 快速實踐】策略梯度算法 (PG)

PG&#xff08;1984&#xff0c;Sutton&#xff09; 核心改進點 策略梯度算法 (PG): 直接對策略函數進行建模&#xff0c;可以適用于連續的動作空間 model-free, on-policy, PG, stochastic 策略 核心改進點說明策略梯度優化通過Actor網絡直接優化策略&#xff0c;適應連續動作…

G1垃圾回收器中YoungGC和MixedGC的區別

在 G1 垃圾回收器中&#xff0c;Mixed GC 和 Young GC 的區別主要體現在以下幾個方面&#xff1a; 作用范圍 Young GC&#xff1a;僅針對年輕代中的Region進行回收&#xff0c;包括 Eden 區和 Survivor 區的 Region。Mixed GC&#xff1a;會回收所有年輕代的 Region 以及部分…

從LLM到AI Agent的技術演進路徑:架構解析與實現邏輯

人工智能技術正經歷從基礎語言模型到智能執行體的關鍵躍遷。解析LLM→RAG→Agent的技術演進三層架構&#xff0c;拆解大模型與知識庫、工具鏈的融合機理&#xff0c;揭示感知-決策-執行閉環系統的構建邏輯。通過架構范式解析、代碼實現示例及多模態實踐案例&#xff0c;為開發者…

commix

Commix 基礎用法和高級用法 基礎用法 Commix 是一個自動化的命令行注入工具&#xff0c;用于檢測和利用 Web 應用程序中的命令注入漏洞。以下是基本使用方法&#xff1a; 基本掃描 python commix.py -u "http://example.com/vuln.php?id1"指定注入點 python commi…

Git刪除指定歷史版本

問題&#xff1a; 在Git提交版本&#xff0c;有時有些小版本相比較于后續的大版本&#xff0c;都會包含&#xff0c;且后續存在的意義不太大&#xff0c;一般認為是可以刪除的。或者&#xff0c;中間一些版本有問題但是也提交了&#xff0c;拉取這些版本根本沒用&#xff0c;這…

使用 Pandas 進行多格式數據整合:從 Excel、JSON 到 HTML 的處理實戰

前言 在數據處理與分析的實際場景中&#xff0c;我們經常需要整合不同格式的數據&#xff0c;例如 Excel 表格、JSON 配置文件、HTML 報表等。本文以一個具體任務&#xff08;藍橋杯模擬練習題&#xff09;為例&#xff0c;詳細講解如何使用 Python 的 Pandas 庫結合其他工具&…

今日行情明日機會——20250425

指數依然在震蕩&#xff0c;等待方向選擇&#xff0c;整體量能不搞但個股紅多綠少。 2025年4月25日漲停板行業方向分析如下&#xff1a; 一、核心行業方向及驅動邏輯 一季報增長&#xff08;17家漲停&#xff09; 核心個股&#xff1a;惠而浦、鴻博股份、衛星化學驅動邏輯&am…

Python 快速獲取Excel工作表名稱

文章目錄 前言準備工作Python 獲取Excel中所有工作表的名稱Python 獲取Excel中隱藏工作表的名稱 前言 在數據分析與辦公自動化領域&#xff0c;通過Python處理Excel文件已成為必備技能。通過獲取工作表名稱&#xff0c;我們可以&#xff1a; 快速了解文件結構自動化處理多工作…

寧德時代25年時代長安動力電池社招入職測評SHL題庫Verify測評語言理解數字推理真題

測試分為語言和數字兩部分&#xff0c;測試時間各為17分鐘&#xff0c;測試正式開始后不能中斷或暫停

ECMAScript 1(ES1):JavaScript 的開端

1. 版本背景與發布 ●發布時間&#xff1a;1997 年 6 月&#xff0c;由 ECMA International 正式發布&#xff0c;標準編號為 ECMA-262。 ●歷史意義&#xff1a;ES1 是 JavaScript 的首個標準化版本&#xff0c;結束了 Netscape Navigator 與 Internet Explorer 瀏覽器間腳本語…

C語言面試高頻題——define 和typedef 的區別?

1. 基本概念 (1) #define 定義&#xff1a;#define 是預處理指令&#xff0c;用于定義宏。作用&#xff1a;在編譯之前進行文本替換。語法&#xff1a;#define 宏名 替換內容示例&#xff1a;#define PI 3.14159 #define SQUARE(x) ((x) * (x))(2) typedef 定義&#xff1a;…

【自然語言處理與大模型】模型壓縮技術之蒸餾

知識蒸餾是一種模型壓縮技術&#xff0c;主要用于將大型模型&#xff08;教師模型&#xff09;的知識轉移到更小的模型&#xff08;學生模型&#xff09;中。在大語言模型領域&#xff0c;這一技術特別重要。 知識蒸餾的核心思想是利用教師模型的輸出作為軟標簽&#xff08;sof…

PHP CURL發送POST請求(支持HEADER參數配置)

/** POST請求(raw數據請求,支持HEADER參數配置) * @param $url * @param $datas 支持數組或字符串 * # $CURLOPT_HTTPHEADER = [ X-AjaxPro-Method:ShowList, Content-Type: application/json; charset=utf-8, Content-Length: . strlen($data_string)]; …

利用JMeter代理服務器方式實現高效壓測

前言 在當今快節奏的互聯網時代&#xff0c;確保Web應用和服務能夠在高負載下穩定運行變得至關重要。無論是電子商務平臺、社交媒體網絡還是在線教育服務&#xff0c;用戶對網站響應速度和穩定性的期望從未如此之高。因此&#xff0c;性能測試不再是一個可選項&#xff0c;而是…

【JavaWeb后端開發04】java操作數據庫(JDBC + Mybatis+ yml格式)詳解

文章目錄 1. 前言2. JDBC2.1 介紹2.2 入門程序2.2.1 DataGrip2.2.2 在IDEA執行sql語句 2.3 查詢數據案例2.3.1 需求2.3.2 準備工作2.3.3 AI代碼實現2.3.4 代碼剖析2.3.4.1 ResultSet2.3.4.2 預編譯SQL2.3.4.2.1 SQL注入2.3.4.2.2 SQL注入解決2.3.4.2.3 性能更高 2.4 增刪改數據…