一文詳解C++20新特性
1、模塊
C++ 20 中正式引入了模塊的概念,模塊是一個用于在翻譯單元間分享聲明和定義的語言特性。它們可以在某些地方替代使用頭文件。
其主要優(yōu)點如下:
- 沒有頭文件。
- 聲明實現(xiàn)仍然可分離, 但非必要。
- 可以顯式指定導(dǎo)出哪些類或函數(shù)。
- 不需要頭文件重復(fù)引入宏(include guards)。
- 模塊之間名稱可以相同,并且不會沖突。
- 模塊只處理一次,編譯更快(頭文件每次引入都需要處理,需要通過 pragma once 約束)。7. 預(yù)處理宏只在模塊內(nèi)有效。
- 模塊的引入與引入順序無關(guān)。
用法
- 定義模塊(math.ixx)
// 模塊聲明(模塊名:math)
export module math;
// 導(dǎo)出函數(shù)(外部可訪問)
export int add(int a, int b) {
return a + b;
}
// 內(nèi)部函數(shù)(僅模塊內(nèi)可見)
int mul(int a, int b) {
return a * b;
}
- 使用模塊(main.cpp)
// 導(dǎo)入模塊(無需頭文件,直接用)
import math;
#include <iostream>
int main() {
std::cout << add(2, 3) << std::endl; // 輸出5(可訪問導(dǎo)出的add)
// std::cout << mul(2, 3) << std::endl; // 編譯錯誤:mul未導(dǎo)出
return 0;
}
2、協(xié)程
C++20 引入無棧協(xié)程(非協(xié)程庫,僅底層機(jī)制),是可掛起 / 恢復(fù)的特殊函數(shù)(非 main 函數(shù)),支持用同步寫法實現(xiàn)異步邏輯;函數(shù)內(nèi)含co_await/co_yield/co_return任一關(guān)鍵字即為協(xié)程,協(xié)程不搶占內(nèi)核調(diào)度,僅由線程調(diào)用。
| 關(guān)鍵字 | 作用 |
|---|---|
| co_yield some_value | 掛起協(xié)程并保存狀態(tài),向調(diào)用者返回some_value |
| co_await some_awaitable | 若some_awaitable未就緒,掛起協(xié)程并保存狀態(tài);就緒后恢復(fù)執(zhí)行 |
| co_return some_value | 終止協(xié)程,向調(diào)用者返回some_value(協(xié)程徹底結(jié)束) |
3、<=> 三向比較運算符
比較結(jié)果如下
(a <=> b) < 0 // 如果 a < b 則為 true
(a <=> b) > 0 // 如果 a > b 則為 true
(a <=> b) == 0 // 如果 a 與 b 相等或者等價 則為 true
類似于C的strcmp 函數(shù)返回-1, 0, 1
一般情況: 自動生成所有的比較操作符, 如果對象是結(jié)構(gòu)體則逐個比較, 可以用下面代碼代替所有的比較運算符
auto X::operator<=>(const Y&) = default;
int num1 = 100, num2 = 100;
if ((num1 <=> num2) < 0) {
cout << "num1 < num2" << endl;}
else if ((num1 <=> num2) > 0) {
cout << "num1 > num2" << endl;}
else {
cout << "num1 = num2" << endl;}
4、范圍 ranges
C++20 引入std::ranges(范圍庫),是對傳統(tǒng) STL 算法的增強(qiáng),以 “范圍”(容器、數(shù)組、視圖等)為核心,簡化遍歷 / 算法調(diào)用,支持鏈?zhǔn)讲僮?,且兼容原?STL 容器,大幅提升代碼簡潔性和可讀性。
#include <ranges>
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> vec = {1,2,3,4,5};
// 范圍遍歷:自動迭代,無需手動寫begin()/end()
for (int i : vec | ranges::views::filter([](int x){ return x%2==0; })) {
cout << i << " "; // 輸出:2 4
}
return 0;
}
5、日期和時區(qū)
C++20 引入std::chrono增強(qiáng)的日期 / 時區(qū)庫,首次標(biāo)準(zhǔn)化了日期(年 / 月 / 日)、時間(時 / 分 / 秒)和時區(qū)的統(tǒng)一處理,替代傳統(tǒng)零散的時間操作方式,支持本地時間、UTC 時間、時區(qū)轉(zhuǎn)換等核心能力。
#include <chrono>
#include <iostream>
using namespace std;
using namespace chrono;
int main() {
// 1. 獲取當(dāng)前系統(tǒng)時間(UTC)
auto now_utc = system_clock::now();
// 轉(zhuǎn)換為日期(年/月/日)
year_month_day ymd = floor<days>(now_utc);
cout << ymd.year() << "-" << ymd.month() << "-" << ymd.day() << endl;
// 2. 時區(qū)轉(zhuǎn)換(UTC→本地時區(qū))
zoned_time local_tz{current_zone(), now_utc};
cout << "本地時間:" << local_tz << endl;
return 0;
}
6、格式化
C++20 引入std::format(格式化庫),替代傳統(tǒng)的printf/cout拼接,支持類型安全的字符串格式化
#include <format>
#include <string>
#include <iostream>
using namespace std;
int main() {
// 基礎(chǔ)格式化:替代printf("%d + %d = %d", a, b, a+b)
int a = 5, b = 3;
string res = format("{} + {} = {}", a, b, a + b);
cout << res << endl; // 輸出:5 + 3 = 8
// 帶格式控制(指定寬度、精度、進(jìn)制)
cout << format("數(shù)字:{:5d},十六進(jìn)制:{:x},浮點數(shù):{:.2f}", 123, 255, 3.1415) << endl;
// 輸出:數(shù)字: 123,十六進(jìn)制:ff,浮點數(shù):3.14
return 0;
}
7、跨度
C++20 引入std::span(跨度),是對連續(xù)內(nèi)存區(qū)域(數(shù)組、vector、C 數(shù)組等)的「輕量級只讀 / 可寫視圖」,僅存儲指針 + 長度,無內(nèi)存拷貝,可安全替代裸指針 / 數(shù)組,簡化連續(xù)內(nèi)存的訪問與傳遞。
#include <span>
#include <vector>
#include <iostream>
using namespace std;
// 替代傳統(tǒng)的「指針+長度」傳參,更安全
void print_span(span<int> s) {
for (int i : s) cout << i << " ";
}
int main() {
int arr[] = {1,2,3,4};
vector<int> vec = {5,6,7};
// 1. 綁定數(shù)組(自動推導(dǎo)長度)
span<int> s1(arr);
print_span(s1); // 輸出:1 2 3 4
// 2. 綁定vector(無拷貝,僅視圖)
span<int> s2(vec);
s2[0] = 10; // 修改視圖會同步修改原vector
cout << vec[0] << endl; // 輸出:10
// 3. 切片(取部分元素)
span<int> s3 = s1.subspan(1, 2); // 從索引1開始,取2個元素
print_span(s3); // 輸出:2 3
return 0;
}
8、并發(fā)
C++20 在原有并發(fā)基礎(chǔ)上增強(qiáng)了并發(fā)能力,核心新增std::jthread(可自動 join 的線程)、std::latch/barrier(同步原語)、std::stop_token(線程取消機(jī)制),同時完善原子操作和異步任務(wù),讓并發(fā)編程更安全、易用,減少手動管理線程的出錯風(fēng)險。
- std::jthread(安全線程,替代 std::thread)增強(qiáng)版線程,析構(gòu)自動 join,支持取消
#include <jthread>
#include <iostream>
using namespace std;
void task(int n) {
cout << "線程執(zhí)行:" << n << endl;
}
int main() {
// jthread析構(gòu)時自動join,無需手動調(diào)用(避免std::thread的析構(gòu)崩潰)
jthread t(task, 10);
// 無需寫t.join(),t銷毀時自動完成
return 0;
}
- 線程取消(stop_token + jthread)配合 jthread 實現(xiàn)安全的線程取消
void cancelable_task(stop_token st, int n) {
for (int i=0; i<n; ++i) {
// 檢查是否收到取消信號
if (st.stop_requested()) {
cout << "線程被取消" << endl;
return;
}
cout << "執(zhí)行中:" << i << endl;
}
}
int main() {
jthread t(cancelable_task, 100);
// 發(fā)送取消信號
t.request_stop();
return 0;
}
- std::latch(一次性同步屏障)一次性同步屏障,等待指定數(shù)量線程就緒
#include <latch>
#include <vector>
int main() {
latch l(3); // 需3個線程到達(dá)后,主線程才繼續(xù)
vector<jthread> threads;
for (int i=0; i<3; ++i) {
threads.emplace_back([&l, i]() {
cout << "線程" << i << "就緒" << endl;
l.count_down(); // 計數(shù)減1
});
}
l.wait(); // 等待所有線程就緒
cout << "所有線程就緒,主線程繼續(xù)" << endl;
return 0;
}
到此這篇關(guān)于一文詳解C++20新特性的文章就介紹到這了,更多相關(guān)C++20新特性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的數(shù)學(xué)算法
這篇文章和大家分享一下我個人對十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的想法,目前暫時更新只整數(shù)十進(jìn)制的轉(zhuǎn)換,后續(xù)會更新帶有小數(shù)的進(jìn)制轉(zhuǎn)換,代碼使用c++實現(xiàn)2021-09-09
vs2022項目文件夾內(nèi).vs文件夾容量虛高問題的解決
經(jīng)常會發(fā)現(xiàn)VS的項目文件夾占用空間很大,本文主要介紹了vs2022項目文件夾內(nèi).vs文件夾容量虛高問題的解決,具有一定的參考價值,感興趣的可以了解一下2023-09-09

