C++發展

目錄

?編輯C++ 的發展總結:?編輯

1.?C++ 的早期發展(1979-1985)

2.?C++ 標準化過程(1985-1998)

3.?C++ 標準演化(2003-2011)

4.?C++11(2011年)

5.?C++14(2014年)

6.?C++17(2017年)

7.?C++20(2020年)

8.?C++23(2023年)

1.?C++ 1985: C++ 1.0

主要特性:

示例代碼:

代碼講解:

C++ 1.0 的局限性:

總結:

2.?C++ 1989: C++ 2.0

主要特性:

多重繼承與虛繼承

示例代碼:

代碼講解:

運行輸出:

解釋:

C++ 2.0 的局限性:

總結:

3.?C++ 1990: C++ 3.0

主要特性:

模板的引入

示例代碼:模板示例

代碼講解:

運行輸出:

代碼解釋:

模板的優勢:

C++ 3.0 的局限性:

總結:

4.?C++ 1998: C++98

主要特性:

示例代碼:C++98 的常見特性

代碼講解:

運行輸出:

代碼解釋:

C++98 的局限性:

總結:

5.?C++ 2003: C++03

主要特性和變化:

C++03 與 C++98 的區別:

示例代碼:C++98 和 C++03 的差異

示例代碼:模板特化修復和?SFINAE?改進

代碼解釋:

運行輸出:

C++03 與 C++98 的局限性:

總結:

6.?C++ 2011: C++11

主要新特性:

示例代碼:C++11 特性

代碼解釋:

運行輸出:

C++11 的優勢:

C++11 的局限性:

總結:

7.?C++ 2014: C++14

主要新特性:

示例代碼:C++14 新特性

代碼解釋:

運行輸出:

C++14 的優勢:

C++14 的局限性:

總結:

8.?C++ 2017: C++17

1.?結構化綁定聲明 (Structured Bindings)

示例:

2.?if/else語句中的初始化語句 (If/else with initialization)

示例:

3.?std::optional

示例:

4.?std::string_view

示例:

5.?std::filesystem

示例:

6.?并行算法 (Parallel Algorithms)

示例:

7.?內聯變量 (Inline Variables)

示例:

8.?改進的constexpr

示例:

總結

9.?C++ 2020: C++20

1.?概念 (Concepts)

示例:

2.?范圍 (Ranges)

示例:

3.?協程 (Coroutines)

示例:

4.?三向比較 (Spaceship Operator?<=>)

示例:

5.?模塊 (Modules)

示例:

6.?范圍循環 (Range-based for loop with initializer)

示例:

7.?std::span

示例:

8.?consteval?和?constinit

示例:

總結

10.?C++ 2023: C++23

1.?改進的常量表達式(constexpr)

示例:

2.?std::expected

示例:

3.?范圍(Ranges)庫增強

示例:

4.?std::format?改進

示例:

5.?explicit?改進

示例:

6.?std::span?支持的改進

示例:

7.?新的屬性([[likely]]?和?[[unlikely]])

示例:

總結

?編輯

C++ 的發展總結:

C++ 是由?Bjarne Stroustrup?于 1979 年在貝爾實驗室(Bell Labs)開始開發的,最初是作為 C 語言的一個擴展,目的是在不喪失 C 語言高效性的基礎上,提供面向對象編程的特性。C++ 的發展歷程可以分為以下幾個重要階段:

C++ 的早期發展1979-1985
C++ 標準化過程1985-1998
C++ 標準演化2003-2011
C++112011年
C++142014年
C++172017年
C++202020年
C++232023年

1.?C++ 的早期發展(1979-1985)

  • 1979年:C++ 的前身?"C with Classes"?出現。Bjarne Stroustrup 在貝爾實驗室的工作中,設計了一個擴展 C 語言的工具,該工具為 C 語言增加了類(class)、構造函數和析構函數等面向對象特性。它的設計目標是提高程序的可重用性,并通過封裝數據和方法的方式增強程序結構。
  • 1983年:C with Classes 更名為 **C++**,并發布了第一版 C++ 語言,開始引入類、繼承、多態等面向對象的特性,雖然這些特性并不完善,但已經為后來的發展奠定了基礎。
  • 1985年:C++ 語言的第一個標準版本發布。Stroustrup 為此編寫了《C++ Programming Language》一書,詳細介紹了 C++ 的語法、特性和編程模型。

2.?C++ 標準化過程(1985-1998)

  • 1989年:C++ 的第一個國際標準草案發布,作為一種較為成熟的語言,逐漸被越來越多的開發者使用。
  • 1990年:C++ 被納入國際標準化組織(ISO)的標準化過程。這個過程中,C++ 逐步加入了更多的語言特性,如模板、異常處理、名字空間等。
  • 1998年:C++98 標準發布,這是 C++ 語言的第一個正式標準版本。C++98 通過增加模板支持、標準庫(如 STL)和異常處理機制,使得 C++ 語言更加全面和功能強大,成為當時最主流的編程語言之一。

3.?C++ 標準演化(2003-2011)

  • 2003年:C++03 標準發布,主要是對 C++98 標準的修正和小幅改進,修復了一些語言特性中的小錯誤,并未引入重大的新特性。
  • 2007年:ISO 發布了 C++0x 標準草案,該標準最終演變為 C++11。在 C++0x 的過程中,許多新的特性開始得到提出和采納,如?自動類型推導右值引用lambda 表達式并發編程?等。C++11 的標準化過程歷時多年,經歷了大量的討論和修改。

4.?C++11(2011年)

  • 2011年:C++11 正式發布,它是 C++ 語言的一個重大變革,包含了大量的新特性,標志著 C++ 語言進入了一個全新的時代。C++11 的主要特性包括:
    • 自動類型推導auto);
    • 右值引用移動語義&&std::move);
    • Lambda 表達式
    • 線程支持std::thread);
    • 智能指針std::unique_ptrstd::shared_ptr);
    • 類型推導decltype)等。
  • C++11 的引入極大提升了 C++ 語言的表達力和現代化程度,使得 C++ 編程更具靈活性和高效性。

5.?C++14(2014年)

  • 2014年:C++14 發布,相較于 C++11,C++14 更像是一個小規模的優化和修復版本。C++14 主要增強了 C++11 中的特性,如 Lambda 表達式的泛型支持、std::make_unique?的引入、decltype(auto)?的改進等。此外,還修復了一些編譯器和實現中的問題。
  • C++14 讓 C++11 中的很多新特性變得更加穩定,增加了可編程性和工具支持。

6.?C++17(2017年)

  • 2017年:C++17 發布,這個版本包含了一些有意義的語言特性和標準庫增強。主要特性包括:
    • **std::optional**:用于表示可能為空的值;
    • 結構化綁定聲明auto [a, b] = tuple;);
    • if?和?switch?中的初始化語句
    • **std::filesystem**:用于處理文件和目錄的標準庫;
    • **改進的?std::string?和?std::array**;
    • 并行算法std::for_each?等支持并行執行)。
  • C++17 不僅增強了語言本身的功能,還進一步加強了對現代硬件和多核處理器的支持,增強了性能和并行計算能力。

7.?C++20(2020年)

  • 2020年:C++20 發布,是 C++ 語言歷史上一個非常重要的版本,帶來了許多令人興奮的新特性:
    • 模塊(Modules):改善頭文件管理,減少編譯時間;
    • 三方比較操作符<=>): 用于自動生成比較操作符(比如?==,?!=,?<,?<=,?>,?>=);
    • 協程(Coroutines):使得異步編程更加簡潔;
    • 概念(Concepts):提供更強的類型約束機制,使模板編程更加安全;
    • 范圍 for 循環改進:更簡潔的語法和強大的靈活性;
    • **std::span**:處理數組和內存塊的輕量級對象;
    • 改進的標準庫:包括?std::formatstd::rangesstd::calendar?等。
  • C++20 為 C++ 帶來了大量的現代化特性,并進一步提升了語言的表達能力、性能和并發編程的支持。

8.?C++23(2023年)

  • 2023年:C++23 發布,雖然其變化相較于 C++20 比較平穩,但仍然包含了一些重要的改進和修復:
    • 新的標準庫功能:例如,std::expectedstd::generator?和?std::ranges?的進一步改進;
    • 語言增強:對模板和類型推導的改進,增強了語言的靈活性和可讀性;
    • 性能優化:進一步增強編譯器對并行、異步和內存管理的支持。
  • C++23 標志著 C++ 語言持續向現代化發展,并且對性能和并發編程的支持進一步加強。
  1. 從面向過程到面向對象:最初的 C++ 語言只是在 C 語言的基礎上增加了類和面向對象的特性,經過多年發展,C++ 在保留 C 語言高效性的同時,也吸收了面向對象、泛型編程和函數式編程的優勢,成為了一門多范式的語言。

  2. 標準化過程:從 C++98 到 C++11,再到 C++14、C++17 和 C++20,C++ 逐漸成為一種具有廣泛應用的編程語言,每個版本都帶來了一些新的特性和增強,逐步適應現代軟件開發的需求。

  3. 現代化與性能:C++ 在引入面向對象特性后,也逐步加入了并行計算、內存管理、泛型編程、協程等現代編程特性,使得它在高性能計算、系統開發、游戲開發和金融等領域仍然占有一席之地。

C++ 的發展歷程體現了它強大的靈活性和持久生命力,C++ 不斷演進,始終保持著與時俱進的能力,成為全球使用最廣泛的編程語言之一。

C++ 的發展歷程可以分為多個版本階段,每個版本都帶來了新的語言特性、庫的改進和標準的增強。下面是 C++ 各個版本的主要變化和特性介紹:

1.?C++ 1985: C++ 1.0

  • 最初版本:由貝爾實驗室的?Bjarne Stroustrup?在 1980 年代初期開發。
  • 主要特點
    • 在 C 語言的基礎上加入了面向對象編程(OOP)特性。
    • 支持類、繼承、多態、封裝等面向對象的基本特性。
    • 引入了函數和運算符重載。

C++ 1.0?是由?Bjarne Stroustrup?在貝爾實驗室開發的第一版 C++ 編程語言。它是在 C 語言的基礎上加入了面向對象編程(OOP)的特性,因此也被稱為是“C with Classes”(C 帶類)。C++ 1.0 并不是一個標準化的語言版本,而是一個實驗性語言,它為后來的 C++ 標準奠定了基礎。

主要特性:
  1. 類與對象:C++ 1.0 引入了面向對象編程的核心概念,最初的類和對象支持比較簡單。

    • 類是 C++ 中的基本構造,用于封裝數據和功能。
    • 對象是類的實例,表示實際的數據和行為。
  2. 函數和運算符重載:C++ 1.0 支持函數重載和運算符重載,使得程序員可以根據需要定義不同版本的函數或操作符。

  3. 基本繼承:C++ 1.0 支持從一個類繼承另一個類,使得可以構建更為復雜的類結構。

  4. 無標準庫:當時的 C++ 語言沒有像現代 C++ 那樣的標準庫。數據結構和算法通常依賴開發者自己編寫。

示例代碼:

C++ 1.0 版本的代碼相對簡單。以下是一個典型的 C++ 1.0 示例,演示了類的定義、對象創建、繼承以及運算符重載。

#include <iostream>
using namespace std;// 定義一個類
class Box {
private:double length;   // 長度double breadth;  // 寬度double height;   // 高度public:// 構造函數Box(double l, double b, double h) {length = l;breadth = b;height = h;}// 計算體積的方法double volume() {return length * breadth * height;}// 運算符重載Box operator+(const Box& b) {// 返回一個新的 Box 對象,體積相加return Box(length + b.length, breadth + b.breadth, height + b.height);}
};// 主函數
int main() {// 創建對象Box box1(3.5, 1.2, 2.0);Box box2(1.0, 2.0, 3.0);// 計算并輸出 box1 的體積cout << "Box1 Volume: " << box1.volume() << endl;// 運算符重載使用示例Box box3 = box1 + box2;cout << "Box3 Volume (box1 + box2): " << box3.volume() << endl;return 0;
}

代碼講解:

  • **類?Box**:定義了一個包含?lengthbreadth?和?height?的類,用于表示一個盒子,并且提供了一個計算體積的方法?volume()
  • 構造函數:用于初始化?Box?對象,設置它的長度、寬度和高度。
  • 運算符重載:使用?operator+?重載運算符?+,使得兩個?Box?對象相加時,返回一個新的?Box?對象,長度、寬度和高度分別相加。
  • 在?main()?中創建對象:通過構造函數創建了?box1?和?box2,并計算它們的體積。在計算?box3?的體積時,使用了重載的加法運算符。

C++ 1.0 的局限性:

  • 缺少模板:當時的 C++ 并不支持模板(泛型編程),模板編程是后來在 C++ 1990 和 1998 標準中引入的。
  • 沒有標準庫:沒有現代 C++ 的 STL(標準模板庫),因此沒有常用的容器、算法等功能。
  • 繼承的支持較為基礎:C++ 1.0 支持繼承,但還沒有引入多態、虛函數等更高級的特性。

總結:

C++ 1.0 是 C++ 語言的初步版本,它為面向對象編程提供了基礎設施,并通過類、對象、繼承、重載等功能擴展了 C 語言的功能。雖然當時的 C++ 功能較為簡單,但它為后續版本的語言特性打下了基礎,并引領了 C++ 向更強大的方向發展。

2.?C++ 1989: C++ 2.0

  • 增強功能
    • 多重繼承:支持多個基類的繼承。
    • 虛繼承:解決多重繼承中的“菱形繼承”問題,確保繼承層次中的基類只有一份副本。
    • 抽象類:引入了純虛函數(抽象類)的概念,使得類能夠定義接口。

C++ 2.0?是 C++ 語言的第二個重要版本,發布于 1989 年。C++ 2.0 在 C++ 1.0 的基礎上進行了重要的擴展和改進,引入了多個新特性,特別是?多重繼承?和?虛繼承。這些新特性使得 C++ 的面向對象編程能力得到了顯著增強。C++ 2.0 為后來的 C++ 語言標準奠定了許多重要基礎。

主要特性:
  1. 多重繼承:C++ 2.0 引入了多重繼承的支持,使得一個類可以繼承多個基類,從而可以組合多個類的功能。
  2. 虛繼承:為了解決多重繼承帶來的“菱形繼承”問題(即一個類通過多個繼承路徑繼承同一個基類),C++ 2.0 引入了?虛繼承?的概念。虛繼承確保通過多個繼承路徑繼承的同一個基類只有一份副本。
  3. 虛函數:繼續擴展了對面向對象編程的支持,尤其是通過?虛函數?機制,使得 C++ 支持?運行時多態
  4. 更強的類型檢查:C++ 2.0 對類型檢查進行了增強,使得語言的類型系統更加嚴格和安全。

多重繼承與虛繼承

C++ 2.0 的最大變化之一就是支持?多重繼承,并且引入了?虛繼承?來解決多重繼承可能引起的問題。在多重繼承中,如果一個類繼承自多個基類,并且這些基類有公共的祖先類,那么在派生類中會有重復的祖先類副本,這時就可能出現問題。虛繼承解決了這一問題,通過確保只有一個祖先類副本,從而避免了數據冗余和潛在的錯誤。

示例代碼:

以下是一個簡單的示例,演示了?多重繼承?和?虛繼承?的概念。

#include <iostream>
using namespace std;// 基類A
class A {
public:A() { cout << "Class A constructor" << endl; }void showA() { cout << "Class A" << endl; }
};// 基類B
class B {
public:B() { cout << "Class B constructor" << endl; }void showB() { cout << "Class B" << endl; }
};// 基類C,虛繼承A
class C : virtual public A {
public:C() { cout << "Class C constructor" << endl; }void showC() { cout << "Class C" << endl; }
};// 派生類D,虛繼承A和B
class D : public C, public B {
public:D() { cout << "Class D constructor" << endl; }void showD() { cout << "Class D" << endl; }
};int main() {// 創建派生類對象DD d;d.showA(); // 來自基類Ad.showB(); // 來自基類Bd.showC(); // 來自基類Cd.showD(); // 來自派生類Dreturn 0;
}

代碼講解:

  • 類 A 和 BA?和?B?是兩個基類,都有自己的構造函數和成員函數。A?有一個?showA()?函數,B?有一個?showB()?函數。
  • 類 CC?類繼承了?A?類,并使用?virtual?關鍵字進行?虛繼承。這樣,在?C?的子類中,如果有多個繼承自?A?的路徑,它們會共享同一個?A?類副本,避免了重復數據。
  • 類 DD?類從?C?和?B?繼承,并且通過虛繼承機制共享了?A?類的副本。
  • 輸出
    • 當?D?類的對象被創建時,首先調用?AB?和?C?的構造函數,再調用?D?的構造函數。
    • showA()showB()?和?showC()?分別調用了從基類繼承的成員函數。

運行輸出:

Class A constructor
Class B constructor
Class C constructor
Class D constructor
Class A
Class B
Class C
Class D

解釋:

  • 虛繼承C?類通過?virtual public A?虛繼承了?A?類,保證了通過?D?類的繼承關系,A?類只有一份副本。即使?D?類是通過?B?和?C?兩個路徑繼承?AA?類也只會被構造一次。
  • 多重繼承D?類通過多重繼承繼承了?B?和?C,因此?D?類擁有?B?和?C?類的功能。

C++ 2.0 的局限性:

  • 沒有命名空間:C++ 2.0 并沒有引入命名空間(namespace),因此容易出現命名沖突的問題。
  • 沒有模板支持:模板編程(如函數模板和類模板)在 C++ 2.0 中還沒有出現,這一特性是在 C++ 3.0 中引入的。
  • 繼承體系較為簡化:雖然支持多重繼承和虛繼承,但對繼承體系的支持仍較為基礎,隨著 C++ 后續版本的發布,繼承和多態的功能會得到更完善的支持。

總結:

C++ 2.0 通過引入?多重繼承?和?虛繼承?大大增強了 C++ 的面向對象能力,使得 C++ 成為一種更強大的編程語言。這些特性讓 C++ 能夠支持更復雜的類層次結構,解決了多重繼承中的一些難題。雖然 C++ 2.0 語言仍然很基礎,但它為 C++ 后續版本的更高級特性,如模板和更復雜的類型系統,奠定了基礎。

3.?C++ 1990: C++ 3.0

  • 功能增強
    • 模板:引入了模板(函數模板和類模板),開始支持泛型編程。
    • 標準庫:初步支持了標準模板庫(STL)的概念,雖然 STL 直到后來的版本才成為標準。

C++ 3.0?是 C++ 語言的第三個版本,發布于 1990 年。相比于前兩個版本,C++ 3.0 在語言特性和功能上做出了重要的擴展,最為關鍵的就是引入了?模板?的支持,這是 C++ 語言向?泛型編程?過渡的重要一步。模板的引入使得 C++ 支持編寫與類型無關的代碼,從而使得編程變得更加靈活和強大。

主要特性:
  1. 模板(Templates)

    • 函數模板:允許定義可以接受不同類型參數的函數。
    • 類模板:允許定義可以接受不同類型參數的類。模板是 C++ 語言中泛型編程的基礎。
  2. 增強的類型系統

    • 支持更復雜的類型定義和類型推導。
    • 改進了類和對象的類型推斷機制。
  3. 基本的標準庫(STL的雛形)

    • 盡管 C++ 3.0 本身并沒有正式定義標準模板庫(STL),但它開始支持類似 STL 的一些容器和算法概念,為未來 STL 的引入奠定了基礎。
  4. 支持虛函數、運算符重載等特性

    • C++ 3.0 繼續擴展了面向對象編程的支持,增強了對繼承、多態、運算符重載等特性的支持。

模板的引入

C++ 3.0 的核心改進就是引入了模板機制,使得函數和類能夠接受參數類型作為模板參數。這使得 C++ 能夠支持泛型編程,從而能夠編寫類型安全且重用性更高的代碼。

示例代碼:模板示例

以下是一個簡單的示例,展示了如何在 C++ 3.0 中使用?函數模板?和?類模板

#include <iostream>
using namespace std;// 函數模板:計算兩個數字的最大值
template <typename T>
T getMax(T a, T b) {return (a > b) ? a : b;
}// 類模板:定義一個簡單的容器類
template <typename T>
class Box {
private:T value;
public:Box(T v) : value(v) {}T getValue() { return value; }void setValue(T v) { value = v; }
};int main() {// 使用函數模板int x = 10, y = 20;cout << "Max of x and y: " << getMax(x, y) << endl;double a = 3.14, b = 2.71;cout << "Max of a and b: " << getMax(a, b) << endl;// 使用類模板Box<int> intBox(100);cout << "Box contains: " << intBox.getValue() << endl;intBox.setValue(200);cout << "Updated Box contains: " << intBox.getValue() << endl;Box<double> doubleBox(3.14159);cout << "Box contains: " << doubleBox.getValue() << endl;return 0;
}

代碼講解:

  • **函數模板?getMax**:

    • getMax?是一個函數模板,它接受兩個類型為?T?的參數,返回它們中的最大值。
    • T?是一個類型參數,可以是任何數據類型(如?intdouble?等),當調用模板函數時,編譯器會根據傳入的參數類型推導出?T?的具體類型。
  • **類模板?Box**:

    • Box?是一個類模板,它有一個類型為?T?的成員變量?value
    • 構造函數接受一個?T?類型的參數來初始化?value,并提供了?getValue?和?setValue?方法來訪問和修改?value

運行輸出:

Max of x and y: 20
Max of a and b: 3.14
Box contains: 100
Updated Box contains: 200
Box contains: 3.14159

代碼解釋:

  • getMax?函數模板:在?main()?中,分別使用了?int?和?double?類型的參數來調用?getMax?函數模板。編譯器根據傳入的參數類型推導出?T?的類型。
  • Box?類模板Box<int>?和?Box<double>?分別是使用?int?和?double?類型的類模板實例化出來的對象。每個?Box?對象可以存儲不同類型的數據。

模板的優勢:

  • 代碼重用:通過模板,函數和類可以支持多種不同的類型,而不需要為每個類型編寫重復的代碼。
  • 類型安全:模板在編譯時進行類型檢查,確保類型的正確性,避免了運行時的類型錯誤。

C++ 3.0 的局限性:

  • 模板特性較為基礎:C++ 3.0 中的模板機制較為簡單,沒有現代 C++ 中復雜的模板特性,如模板特化、SFINAE(Substitution Failure Is Not An Error)等。
  • 標準庫仍然不成熟:盡管模板提供了更多的靈活性,但標準庫并沒有像 C++11 和 C++14 中那樣強大,STL 的概念才剛剛開始萌芽。

總結:

C++ 3.0 是 C++ 語言的一個重要版本,模板的引入是其最大的亮點,標志著 C++ 進入了泛型編程的時代。模板讓 C++ 變得更加靈活,支持更加高效的代碼重用和類型安全的操作。通過函數模板和類模板,C++ 可以在不同類型之間共享代碼,從而極大地提高了開發效率和代碼的可維護性。雖然 C++ 3.0 的模板機制相對簡單,但它為后續的 C++ 標準化進程和更復雜的模板特性奠定了基礎。

4.?C++ 1998: C++98

  • C++ 標準化:C++98 是 C++ 的第一個正式標準版本,由?ISO/IEC 14882:1998?定義。
  • 主要特性
    • STL(標準模板庫):引入了標準模板庫,包括?vectorlistmapset?等容器,及算法(如排序、查找等)。map - C++ Reference? ??set - C++ Reference
    • 命名空間(namespace):為了避免名稱沖突,引入了命名空間。
    • 異常處理:引入了?trycatchthrow?異常處理機制。
    • RTTI(運行時類型信息):引入了?typeid?和?dynamic_cast,允許運行時識別對象的類型。

C++98?是 C++ 語言的第一個國際標準,正式由 ISO(國際標準化組織)在 1998 年發布。C++98 語言標準繼承了 C++ 3.0 的核心特性,并在此基礎上進行了多個重要的改進和規范化。這個版本的 C++ 為標準庫(STL)提供了規范,并開始支持更多的現代編程特性。

主要特性:
  1. 模板

    • C++98 中的模板特性得到了進一步的增強,支持函數模板和類模板,并且模板的使用變得更加廣泛。模板參數可以是類、函數、指針等類型。
  2. 標準模板庫(STL)

sort - C++ Reference

  1. 異常處理

    • C++98 提供了標準化的異常處理機制,使用?try,?catch,?throw?語句來處理運行時錯誤。
  2. 命名空間

    • C++98 引入了?命名空間namespace),用于避免名稱沖突,尤其是在大型項目中。
  3. 虛函數與多態

    • C++98 繼續強化了面向對象編程的支持,特別是對?虛函數?和?多態?的使用。
  4. const 和引用

    • C++98 對?const?關鍵字和引用進行了嚴格的規范,使得編程更加安全。
  5. 函數指針和類型轉換

    • 提供了對?函數指針?和?類型轉換(如?static_cast,?dynamic_cast?等)的支持,增強了 C++ 的靈活性。
  6. 類成員的類型推導

    • C++98 引入了對類成員類型的推導,允許在某些情況下省略類型聲明。
示例代碼:C++98 的常見特性

以下是一個綜合示例,展示了 C++98 中的幾個核心特性,包括模板、標準庫(STL)、命名空間和異常處理。

vector - C++ Reference

#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>namespace MyNamespace {// 模板函數:計算兩個數的最大值template <typename T>T getMax(T a, T b) {return (a > b) ? a : b;}// 使用 STL 容器:vector 和算法void useSTL() {std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};std::sort(vec.begin(), vec.end());std::cout << "Sorted vector: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;}// 異常處理示例void testException() {try {throw std::out_of_range("Index out of range!");} catch (const std::exception& e) {std::cout << "Caught exception: " << e.what() << std::endl;}}
}int main() {// 使用命名空間using namespace MyNamespace;// 使用模板函數int x = 10, y = 20;std::cout << "Max of x and y: " << getMax(x, y) << std::endl;// 使用 STL 容器和算法useSTL();// 測試異常處理testException();return 0;
}

代碼講解:

  • **模板函數?getMax**:

    • 這是一個簡單的模板函數,接受兩個相同類型的參數,并返回它們中的最大值。typename T?表示這是一個模板函數,T?是占位符類型,可以在調用時由編譯器自動推導出。
  • STL 容器和算法

    • 在?useSTL?函數中,使用了?std::vector?來存儲整數數據,并使用?std::sort?算法對數據進行了排序。std::vector?是 C++98 標準庫中的一個動態數組容器,std::sort?是一個算法函數,用于對容器中的元素進行排序。
  • 異常處理

    • testException?函數演示了 C++98 的異常處理機制。在這個函數中,拋出了一個?std::out_of_range?異常,并在?catch?塊中捕獲它,輸出異常的描述信息。

運行輸出:

Max of x and y: 20
Sorted vector: 1 1 2 3 3 4 5 5 5 6 9 
Caught exception: Index out of range!

代碼解釋:

  1. **模板?getMax**:通過模板,可以在運行時自動確定?T?的類型,支持不同的數據類型(如?intdouble?等)。在本例中,它比較了兩個整數?x?和?y
  2. **STL 容器?std::vector?和?std::sort**:std::vector?是一個可以動態調整大小的容器,它存儲一系列元素。std::sort?是一個通用算法,用來對容器中的元素進行排序。
  3. 異常處理:C++98 提供了標準的異常處理機制,允許在代碼運行過程中拋出和捕獲異常,避免程序因錯誤而崩潰。

C++98 的局限性:

  1. 沒有?auto?關鍵字:C++98 中沒有?auto?關鍵字,因此類型推導只能依靠顯式的類型聲明。
  2. **沒有?nullptr**:C++98 中沒有?nullptr,指針使用時可能會引發隱式的類型轉換問題。
  3. 沒有類型推導的?for?循環:C++98 中沒有像 C++11 中那樣的基于范圍的?for?循環(for (auto& elem : container))。
  4. 模板元編程有限:雖然模板功能在 C++98 中已被引入,但對于模板元編程的支持相對有限,模板編程的復雜性和靈活性較低。

總結:

C++98 是 C++ 語言的第一個國際標準版本,它鞏固并標準化了之前 C++3.0 中的許多特性,并加入了?模板?和?STL?等重要特性,使得 C++ 在實際開發中更加高效和靈活。通過模板,C++98 使得代碼可以在不同的數據類型之間重用,同時標準庫(STL)提供了高效的容器和算法支持,大大提高了開發效率。雖然 C++98 為后來的 C++ 標準奠定了基礎,但它在某些領域(如模板編程和自動類型推導)仍存在局限。

5.?C++ 2003: C++03

  • 修復和改進
    • 小的改進:C++03 主要是對 C++98 標準的一些修訂和錯誤修正,沒有引入重大新特性。
    • 支持一些新的編譯器特性,如增強的模板支持、異常安全性等。

C++03?是 C++ 語言的一個小版本更新,它是對?C++98?的修正版本,主要用于解決一些語言上的不一致性和設計上的小問題。C++03 并未引入許多新的功能,而是對 C++98 標準中的一些細節進行了修正和澄清,確保語言的一致性和規范性。這個版本主要集中在語言規范的完善和一些編譯器支持方面。

C++03 的發布并沒有像 C++98 到 C++11 之間的版本那樣進行革命性的更新,因此它在功能上與 C++98 并無太大差異。主要的更新包括對?模板特化SFINAE(Substitution Failure Is Not An Error)等方面的細節修正,確保了編譯器能夠更好地支持標準庫。

主要特性和變化:

  1. 模板的修正和改進

    • C++03 對模板特化和模板元編程做了小的修正,使得編譯器對模板的支持更加一致。
    • 改進了模板在某些邊界情況中的行為,避免了 C++98 中一些不一致或令人困惑的部分。
  2. 標準庫的修正

    • C++03 對標準庫中的一些接口做了微調,解決了 C++98 標準庫中的一些小問題。例如,修復了?std::vector?在某些情況下的行為不一致性,確保了 STL 中的算法與容器的更好兼容性。
  3. 修復了常見的編譯器問題

    • C++03 對一些編譯器的兼容性問題進行了修復,確保不同廠商的編譯器之間有更好的兼容性。
  4. 去除了某些不再使用的特性

    • C++03 刪除了一些在 C++98 中冗余或未被廣泛使用的特性,從而使標準更加精簡和一致。

C++03 與 C++98 的區別:

  • 細節修正:C++03 主要是針對 C++98 標準中存在的某些歧義性和編譯器實現差異進行修正。它并沒有加入新的語言特性,而是專注于優化語言和標準庫的現有特性。
  • STL 和模板的完善:C++03 解決了模板和標準庫的一些小問題,確保標準庫在不同編譯器下的行為一致。

示例代碼:C++98 和 C++03 的差異

由于 C++03 與 C++98 的差異主要體現在語言的細節上,因此以下示例代碼在 C++03 中的表現與 C++98 是相同的。我們展示一些在 C++98 和 C++03 中模板使用的常見問題,這些問題在 C++03 中得到了修正。

示例代碼:模板特化修復和?SFINAE?改進
#include <iostream>
#include <type_traits>// 模板類的默認實現
template <typename T>
class Printer {
public:static void print(const T& value) {std::cout << value << std::endl;}
};// 特化:對于 const 類型的處理
template <typename T>
class Printer<const T> {
public:static void print(const T& value) {std::cout << "const value: " << value << std::endl;}
};// 使用 SFINAE 來選擇函數
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, void>::type
printType(const T& value) {std::cout << "Non-integer value: " << value << std::endl;
}template <typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
printType(const T& value) {std::cout << "Integer value: " << value << std::endl;
}int main() {Printer<int>::print(123);  // 默認模板Printer<const int>::print(456);  // 特化模板printType(123);  // 調用整數版本printType(3.14);  // 調用非整數版本return 0;
}

代碼解釋:

  1. 模板類?Printer?的特化

    • Printer?是一個模板類,在默認情況下,它的?print?函數打印任意類型的值。
    • 特化版本?Printer<const T>?對?const?類型的處理進行了特殊化,使其輸出時帶有 "const value: " 字樣。此特化是在 C++03 中明確規定的,確保了特化行為的統一性。
  2. SFINAE(Substitution Failure Is Not An Error)

    • printType?函數使用了 SFINAE 來根據類型?T?的不同選擇不同的版本。

    • 使用?std::enable_if?和?std::is_integral?來判斷?T?是否為整數類型,并分別調用不同的函數。SFINAE?機制可以避免無效的模板實例化,確保了代碼的類型安全。

    • 如果?T?是整數類型,printType(int)?會被調用;否則,printType(double)?會被調用。

運行輸出:

123
const value: 456
Integer value: 123
Non-integer value: 3.14

C++03 與 C++98 的局限性:

  1. 沒有新的語言特性:C++03 僅僅是 C++98 的修正版本,沒有引入新的語言特性。開發者并未從中獲得像 C++11、C++14、C++17 那樣的重大進展。
  2. 標準庫的改進有限:雖然 C++03 修復了一些標準庫的問題,但與后來的 C++ 標準相比,它的功能仍顯得較為簡單。
  3. 沒有現代化工具:如?autonullptr、范圍?for?循環等特性都沒有出現在 C++03 中,這使得它在一些現代編程需求面前顯得有些過時。

總結:

C++03 是一個對 C++98 的修正版本,主要修復了一些語言規范中的小錯誤和不一致性,改進了模板、STL 和編譯器的兼容性。它并沒有引入新的語言特性,因此在實際使用中,C++98 和 C++03 的差異并不顯著。C++03 主要對 C++98 的一些不明確之處進行了修正,為后續 C++ 標準的進化(如 C++11、C++14)奠定了基礎。對于開發者來說,C++03 更多的是一種穩定性和兼容性更新,而不是一種功能性擴展。

6.?C++ 2011: C++11

  • 現代 C++ 的起點:C++11 是 C++ 的一次重大更新,被廣泛認為是 C++ 語言的“現代化”轉折點。
  • 關鍵特性:
    • 自動類型推斷(auto):使用?auto?關鍵字可以讓編譯器推斷變量類型。
    • 智能指針:引入了?std::unique_ptrstd::shared_ptrstd::weak_ptr,用于自動管理內存,避免內存泄漏。
    • Lambda 表達式:允許定義匿名函數,可以在代碼中更方便地使用函數對象。
    • 并發支持:引入了?<thread>?庫,允許多線程編程。
    • **nullptr**:引入了?nullptr?關鍵字,替代?NULL,提高代碼的類型安全。
    • 右值引用和移動語義:引入右值引用(&&)和?std::move,提高對象傳遞效率,減少不必要的拷貝。
    • 范圍 for 循環:引入了簡潔的范圍?for?循環,簡化容器遍歷。
    • 類型別名(using):引入?using?關鍵字,簡化類型別名定義。
    • 變長模板(Variadic Templates):支持可變參數模板,提高模板的靈活性。

C++11?是 C++ 語言的一個重大更新,正式于 2011 年發布。它引入了大量新的特性和改進,使 C++ 語言更現代化、更加高效和易于使用。C++11 標準的推出,極大地擴展了 C++ 的功能,使得 C++ 開發變得更加靈活、簡潔,同時還提升了性能。

主要新特性:

  1. 自動類型推導(auto

    • auto?關鍵字允許編譯器根據表達式的類型自動推導變量的類型,減少了類型聲明的冗余,提高了代碼可讀性。
  2. 右值引用與移動語義(&&?和?std::move

    • 引入右值引用(&&)和?std::move,實現了?移動語義。通過移動資源而不是復制,顯著提高了效率,尤其在需要大量數據傳輸的場合(如容器操作)。
  3. 范圍?for?循環

    • 引入了范圍?for?循環(range-based for loop),簡化了容器元素的遍歷,避免了傳統迭代器的復雜性。
  4. Lambda 表達式

    • Lambda 表達式允許在函數內定義匿名函數,并且可以捕獲外部變量,極大地增強了函數式編程的支持。
  5. **nullptr**:

    • nullptr?替代了?NULL,它是一個類型安全的空指針常量,消除了?NULL?的類型不匹配問題。
  6. **constexpr**:

    • constexpr?使得可以在編譯時求值的常量表達式更加簡潔,增強了編譯期計算的能力。
  7. 并發編程:<thread>?庫

    • C++11 引入了原生的線程支持,<thread>?庫使得多線程編程變得更加容易和高效。
  8. 類型別名(using

    • using?關鍵字可以用來為類型定義別名,取代了傳統的?typedef,語法更加簡潔。
  9. 強類型枚舉(enum class

    • 引入了強類型枚舉?enum class,避免了傳統枚舉可能產生的隱式轉換和命名沖突問題。
  10. **新標準庫:std::chrono**:

    • C++11 引入了用于處理時間和日期的新標準庫?std::chrono,使得處理時間變得更加直觀和精確。

示例代碼:C++11 特性

下面的代碼示例展示了 C++11 的一些關鍵特性。

#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
#include <functional>// 1. 自動類型推導
void autoExample() {auto x = 10;  // 編譯器自動推導類型為 intauto y = 3.14;  // 編譯器自動推導類型為 doublestd::cout << "x: " << x << ", y: " << y << std::endl;
}// 2. 范圍 for 循環
void rangeBasedFor() {std::vector<int> vec = {1, 2, 3, 4, 5};for (auto& num : vec) {  // 使用范圍 for 遍歷num *= 2;}std::cout << "Doubled values: ";for (const auto& num : vec) {std::cout << num << " ";}std::cout << std::endl;
}// 3. Lambda 表達式
void lambdaExample() {std::vector<int> vec = {1, 2, 3, 4, 5};int sum = 0;// 使用 lambda 表達式進行求和std::for_each(vec.begin(), vec.end(), [&sum](int num) { sum += num; });std::cout << "Sum of elements: " << sum << std::endl;
}// 4. 移動語義和右值引用
class MyClass {
public:MyClass() { std::cout << "Constructor\n"; }MyClass(const MyClass&) { std::cout << "Copy Constructor\n"; }MyClass(MyClass&&) { std::cout << "Move Constructor\n"; }MyClass& operator=(const MyClass&) { std::cout << "Copy Assignment\n"; return *this; }MyClass& operator=(MyClass&&) { std::cout << "Move Assignment\n"; return *this; }
};void moveExample() {MyClass a;MyClass b = std::move(a);  // 使用移動構造函數
}int main() {// 自動類型推導autoExample();// 范圍 for 循環rangeBasedFor();// Lambda 表達式lambdaExample();// 移動語義moveExample();// 使用線程std::thread t([]{ std::cout << "Hello from a thread!\n"; });t.join();  // 等待線程執行完畢return 0;
}

代碼解釋:

  1. **自動類型推導 (auto)**:

    • 使用?auto?關鍵字,編譯器會自動推導變量?x?和?y?的類型,簡化了類型聲明,特別是對于復雜類型(如迭代器和函數返回類型)時非常有用。
  2. 范圍?for?循環

    • 使用 C++11 引入的范圍?for?循環來遍歷容器。這個語法簡潔、直觀,避免了顯式的迭代器操作。
  3. Lambda 表達式

    • 使用?std::for_each?算法與 lambda 表達式結合,計算容器中所有元素的總和。lambda 表達式?[&sum](int num) { sum += num; }?捕獲外部變量?sum?并對容器中的每個元素執行加法操作。
  4. 右值引用與移動語義

    • 在?moveExample?中,通過?std::move?實現了對象?a?的移動,將其資源轉移給對象?b,觸發了移動構造函數而不是拷貝構造函數。
  5. 線程支持

    • 使用 C++11 的?<thread>?庫創建和啟動一個線程,并且通過?join()?等待線程執行完成。std::thread?簡化了多線程編程。

運行輸出:

x: 10, y: 3.14
Doubled values: 2 4 6 8 10
Sum of elements: 15
Move Constructor
Hello from a thread!

C++11 的優勢:

  • 現代化的語法和功能:C++11 引入的眾多新特性大大提升了語言的靈活性和表達力,減少了冗余代碼,使得 C++ 編程更加簡潔、易讀和高效。
  • 性能優化:通過右值引用和移動語義,C++11 使得許多數據傳輸和復制操作得以高效地優化,特別是在容器和大型對象的操作中,性能大幅提升。
  • 并發支持:C++11 將多線程支持納入語言標準,使得并發編程變得更加容易和可靠,減少了對外部庫的依賴。

C++11 的局限性:

  • 學習曲線:盡管 C++11 引入了許多現代化特性,但對一些開發者來說,掌握這些新特性可能需要一定的學習時間。
  • 編譯器支持問題:盡管大部分現代編譯器已經完全支持 C++11,但一些舊的編譯器或開發環境可能存在兼容性問題。

總結:

C++11 是 C++ 語言的一次重大更新,帶來了許多新的語言特性和庫支持,使得 C++ 編程變得更加簡潔、強大和高效。無論是在性能優化、現代語法的引入,還是在并發支持等方面,C++11 都大幅提升了語言的可用性和表達能力。

7.?C++ 2014: C++14

  • 小幅增強:
    • constexpr?的改進:支持更復雜的編譯時常量計算。
    • 二進制字面量:引入了支持二進制常量字面量。
    • auto?的增強:使得?auto?可以推導更加復雜的類型。
    • Lambda 表達式的改進:支持更強的捕獲特性(如捕獲?*this?引用)。

C++14?是 C++ 語言的一個相對較小的更新版本,于 2014 年發布。C++14 并沒有像 C++11 那樣引入大量的新特性,而是對 C++11 中的一些特性進行了修復、增強和小幅優化。它的目標是提高語言和標準庫的穩定性,改進一些 C++11 的邊界情況,增強編譯器的支持,并提供一些性能上的提升。

主要新特性:

  1. 泛型 Lambda 表達式

    • C++14 擴展了 C++11 中的 Lambda 表達式,引入了泛型 Lambda,使得 Lambda 可以接受不同類型的參數而不需要顯式地指定類型。
  2. 變量模板

    • C++14 引入了?變量模板,允許創建像模板函數一樣的模板變量。之前只有函數和類可以是模板,但 C++14 使得變量也可以具有模板特性。
  3. Lambda 表達式的返回類型推導

    • 在 C++14 中,Lambda 表達式可以通過?auto?關鍵字自動推導返回類型。這避免了在 Lambda 表達式中手動指定返回類型的需要。
  4. **std::make_unique**:

    • 引入了?std::make_unique,作為?std::make_shared?的對稱操作,它簡化了對?std::unique_ptr?的創建,避免了不必要的?new?運算符。
  5. **decltype(auto)**:

    • 引入了?decltype(auto)?作為函數返回類型的推導方式,它可以推導出具有精確類型的返回值,支持返回引用類型的自動推導。
  6. 標準庫改進

    • C++14 修復了 C++11 標準庫中的一些問題,并改進了對各種常見編譯器的支持。標準庫中對線程、智能指針、算法等的支持變得更加穩定和高效。
  7. 二進制字面量

    • C++14 引入了二進制字面量(0b?或?0B)的支持,使得表示二進制數更加直觀。
  8. **std::exchange**:

    • 新增了?std::exchange?函數,它可以簡化交換操作,尤其是當你需要交換一個對象并返回其原值時。

示例代碼:C++14 新特性

以下代碼展示了 C++14 中的一些關鍵特性,包括泛型 Lambda、變量模板、decltype(auto)std::make_unique?等。

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>// 1. 泛型 Lambda 表達式
void genericLambda() {auto sum = [](auto a, auto b) { return a + b; };  // 泛型 Lambdastd::cout << "Sum of 3 and 4.5: " << sum(3, 4.5) << std::endl;
}// 2. 變量模板
template <typename T>
T pi = T(3.14159);void variableTemplate() {std::cout << "Pi as float: " << pi<float> << std::endl;std::cout << "Pi as double: " << pi<double> << std::endl;
}// 3. Lambda 表達式的返回類型推導
void lambdaReturnType() {auto multiply = [](auto a, auto b) { return a * b; };std::cout << "Multiply 4 and 5.5: " << multiply(4, 5.5) << std::endl;
}// 4. 使用 std::make_unique
void makeUnique() {auto ptr = std::make_unique<int[]>(5);  // 使用 make_unique 創建動態數組ptr[0] = 10;std::cout << "First element in unique_ptr array: " << ptr[0] << std::endl;
}// 5. 使用 decltype(auto) 推導返回類型
int&& returnRvalue() {int x = 5;return std::move(x);  // 返回右值引用
}void decltypeAuto() {decltype(auto) result = returnRvalue();std::cout << "Rvalue returned: " << result << std::endl;
}// 6. 使用 std::exchange
int increment(int& x) {return std::exchange(x, x + 1);  // 將 x 的當前值賦給函數并更新 x
}void exchangeExample() {int value = 10;int oldValue = increment(value);std::cout << "Old value: " << oldValue << ", New value: " << value << std::endl;
}int main() {// 泛型 LambdagenericLambda();// 變量模板variableTemplate();// Lambda 返回類型lambdaReturnType();// 使用 make_uniquemakeUnique();// 使用 decltype(auto)decltypeAuto();// 使用 std::exchangeexchangeExample();return 0;
}

代碼解釋:

  1. 泛型 Lambda 表達式

    • 通過?auto?來聲明 Lambda 表達式的參數類型,使得 Lambda 可以接受任意類型的參數。這使得 Lambda 表達式更加靈活,可以應用于多種不同的類型。
  2. 變量模板

    • pi?是一個模板變量,它接受一個類型參數?T,并為每個類型提供不同的常量值。在?variableTemplate()?中,演示了如何使用模板變量來獲取?pi?的不同類型值。
  3. Lambda 返回類型推導

    • 使用?auto?關鍵字,Lambda 表達式會自動推導返回類型。在?lambdaReturnType()?中,返回類型是乘積結果的類型,auto?會自動推導出其正確類型。
  4. **std::make_unique**:

    • std::make_unique?用于創建?std::unique_ptr,這是一個智能指針,用于管理動態分配的內存。std::make_unique?是 C++14 引入的,它比直接使用?new?更加安全和方便。
  5. **decltype(auto)**:

    • decltype(auto)?用于推導函數的返回類型,并且支持返回值是引用的情況。在?decltypeAuto()?中,returnRvalue()?返回一個右值引用,通過?decltype(auto)?可以正確地推導出返回類型。
  6. **std::exchange**:

    • std::exchange?是 C++14 引入的一個小工具,它用于交換一個變量的值并返回舊值。在?exchangeExample()?中,std::exchange?用于交換?value?的值并返回交換前的值。

運行輸出:

Sum of 3 and 4.5: 7.5
Pi as float: 3.14159
Pi as double: 3.14159
Multiply 4 and 5.5: 22
First element in unique_ptr array: 10
Rvalue returned: 5
Old value: 10, New value: 11

C++14 的優勢:

  • 增強的類型推導:通過?autodecltype(auto)、泛型 Lambda 表達式等新特性,C++14 提供了更加靈活和精簡的編程體驗。
  • 更強大的 Lambda 表達式:C++14 使得 Lambda 表達式支持更復雜的類型推導和捕獲方式,提升了函數式編程的能力。
  • 內存管理優化std::make_unique?提高了內存管理的安全性和效率,避免了直接使用?new?時可能出現的資源泄漏問題。
  • 簡化的交換操作std::exchange?使得交換操作更加簡潔,尤其是在需要交換并返回原值的場景中。

C++14 的局限性:

  • 更新較小:相比 C++11,C++14 的新特性較少,更多的是對 C++11 特性的增強和補充。因此,C++14 的使用場景更多是在已有代碼的優化和小修小補上。
  • 編譯器支持:盡管大部分現代編譯器支持 C++14,但早期的編譯器可能對一些新特性的支持不完全,開發者在使用這些特性時需要確認編譯器的兼容性。

總結:

C++14 是 C++ 語言的一個小版本更新,主要通過增強和擴展 C++11 中的特性來提升語言的靈活性、可用性和安全性。它引入了泛型 Lambda、變量模板、std::make_unique?等重要特性,并修復了 C++11 中的一些邊界問題。C++14 對于已經使用 C++11 的開發者來說是一個重要的改進,但它的變化相對較小,不會像 C++11 那樣對整個語言體系造成顛覆性的影響。

8.?C++ 2017: C++17

  • 重要更新:
    • 結構化綁定聲明:允許通過?auto [x, y] = pair?等語法,直接解構元組或結構體。
    • **std::filesystem**:引入文件系統庫,提供跨平臺的文件系統操作接口。
    • if?和?switch?初始化:允許在?if?或?switch?語句中直接初始化變量。
    • 并行算法:STL 中的算法庫支持并行執行,如并行排序。
    • **std::optional**:提供了一個容器,可以包含一個值或為空,用于避免空指針的使用。
    • **std::variant**:實現了類似于聯合體的類型,但比 C 的?union?更安全和靈活。
    • **改進的?std::any**:增強了類型安全的通用容器,允許存儲任意類型。

C++17(也被稱為C++ 2017)是C++編程語言的一個重要版本,它在C++11和C++14的基礎上進行了許多改進,增強了語言特性、庫功能以及編譯器支持。C++17的主要亮點包括:

1.?結構化綁定聲明 (Structured Bindings)

C++17 引入了結構化綁定,允許你將一個結構或元組拆分為多個變量,從而讓代碼更加簡潔易讀。

示例:
#include <tuple>
#include <iostream>std::tuple<int, double, std::string> getData() {return {1, 3.14, "Hello, C++17!"};
}int main() {auto [x, y, z] = getData();  // 結構化綁定std::cout << x << ", " << y << ", " << z << std::endl;return 0;
}

輸出:

1, 3.14, Hello, C++17!

2.?if/else語句中的初始化語句 (If/else with initialization)

C++17允許在ifelse語句中進行變量初始化,避免了冗余的變量聲明。

示例:
#include <iostream>int main() {if (int x = 10; x > 5) {std::cout << "x is greater than 5" << std::endl;} else {std::cout << "x is not greater than 5" << std::endl;}return 0;
}

輸出:

x is greater than 5

注意:x只在ifelse的作用域內有效。

3.?std::optional

std::optional?是一個模板類,用來表示一個可能為空的值。它可以用來避免使用空指針或特殊值來表示無效數據。

示例:
#include <iostream>
#include <optional>std::optional<int> findValue(bool found) {if (found) {return 42;} else {return std::nullopt;  // 返回空值}
}int main() {auto value = findValue(true);if (value) {std::cout << "Found value: " << *value << std::endl;} else {std::cout << "Value not found" << std::endl;}return 0;
}

輸出:

Found value: 42

4.?std::string_view

std::string_view是一個輕量級的字符串視圖,避免了復制字符串數據,提供了對字符串的只讀訪問。

示例:
#include <iostream>
#include <string_view>void printString(std::string_view str) {std::cout << str << std::endl;
}int main() {std::string str = "Hello, C++17!";printString(str);  // 不會復制數據return 0;
}

輸出:

Hello, C++17!

5.?std::filesystem

C++17加入了對文件系統操作的標準庫支持,std::filesystem使得處理文件和目錄變得更加方便。

示例:

<iostream> - C++ Reference

#include <iostream>
#include <filesystem>namespace fs = std::filesystem;int main() {fs::path p = "example.txt";if (fs::exists(p)) {std::cout << p << " exists!" << std::endl;} else {std::cout << p << " does not exist." << std::endl;}return 0;
}

輸出:

example.txt does not exist.

6.?并行算法 (Parallel Algorithms)

C++17添加了對并行執行算法的支持,例如使用?std::for_each?和其他標準算法的并行執行。

示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>int main() {std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};std::for_each(std::execution::par, data.begin(), data.end(), [](int& x) {x *= 2;});for (int x : data) {std::cout << x << " ";}return 0;
}

輸出:

2 4 6 8 10 12 14 16 18 

(注意:并行執行可能因環境不同而產生不同的輸出順序)

7.?內聯變量 (Inline Variables)

C++17引入了內聯變量,解決了頭文件中靜態變量帶來的鏈接問題。

示例:
#include <iostream>inline int x = 42;  // 內聯變量int main() {std::cout << x << std::endl;return 0;
}

8.?改進的constexpr

C++17擴展了constexpr的功能,允許在編譯時執行更多的操作,比如動態分配內存和使用if語句。

示例:
#include <iostream>constexpr int factorial(int n) {return (n == 0) ? 1 : n * factorial(n - 1);
}int main() {std::cout << "Factorial of 5: " << factorial(5) << std::endl;return 0;
}

輸出:

Factorial of 5: 120

總結

C++17引入了許多新特性,極大提高了語言的表達力和編程效率,尤其是在簡化代碼、提高性能和增加靈活性方面。對于現代C++開發者來說,熟練掌握這些特性將大大提升開發體驗和代碼質量。

9.?C++ 2020: C++20

  • 重大的新特性:
    • 模塊(Modules):引入了模塊化的支持,替代傳統的頭文件和源文件方式,減少編譯時間。
    • 協程(Coroutines):支持異步編程,簡化了異步函數的編寫。
    • 概念(Concepts):引入了模板約束,使得模板編程更加靈活和易于理解。
    • 范圍(Ranges):增強了容器操作的靈活性和簡潔性,提供了更強大的算法支持。
    • **std::format**:提供了類似 Python 中的格式化字符串功能,簡化了輸出。
    • **consteval?和?constinit**:新關鍵字,用于常量表達式和常量初始化的嚴格控制。
    • **改進的?constexpr**:支持更多的編譯時功能,包括動態內存分配。

C++20 是 C++ 標準的一個重要更新,它在語言特性、庫功能、并發支持等方面進行了大量的擴展和增強。C++20 對語言進行了重要的現代化,使得 C++ 更加高效、簡潔、易用。以下是 C++20 中的一些主要特性及其代碼示例:

1.?概念 (Concepts)

概念是 C++20 的一項新特性,用來約束模板類型。它允許我們更精確地控制模板參數類型,提供編譯時檢查和更好的錯誤信息。

示例:
#include <iostream>
#include <concepts>template <typename T>
concept Incrementable = requires(T a) { ++a; a++; };template <Incrementable T>
T increment(T x) {return ++x;
}int main() {int a = 5;std::cout << increment(a) << std::endl;  // 正常工作// std::string s = "Hello";// std::cout << increment(s) << std::endl; // 編譯錯誤,因為 std::string 不符合 Incrementable 概念return 0;
}

輸出:

6

2.?范圍 (Ranges)

C++20 引入了?std::ranges,為標準庫中的容器和算法提供了更加一致和方便的操作方法,支持通過管道操作符(|)組合算法。

示例:
#include <iostream>
#include <vector>
#include <ranges>int main() {std::vector<int> nums = {1, 2, 3, 4, 5};// 使用管道操作符對容器進行操作auto result = nums | std::views::transform([](int x) { return x * 2; })| std::views::filter([](int x) { return x > 5; });for (int val : result) {std::cout << val << " ";}return 0;
}

輸出:

6 8 10

3.?協程 (Coroutines)

C++20 引入了協程支持,使得編寫異步代碼更加簡潔。協程允許暫停和恢復函數的執行,適用于處理 I/O 操作或其他需要異步操作的場景。

示例:
#include <iostream>
#include <coroutine>struct Task {struct promise_type;using handle_type = std::coroutine_handle<promise_type>;struct promise_type {Task get_return_object() { return Task{handle_type::from_promise(*this)}; }std::suspend_always initial_suspend() { return {}; }std::suspend_always final_suspend() noexcept { return {}; }void unhandled_exception() { std::exit(1); }void return_void() {}};handle_type coro;Task(handle_type h) : coro(h) {}~Task() { coro.destroy(); }void resume() { coro.resume(); }
};Task simpleCoroutine() {std::cout << "Start of coroutine\n";co_await std::suspend_always{};std::cout << "End of coroutine\n";
}int main() {auto coro = simpleCoroutine();coro.resume();  // 啟動協程coro.resume();  // 恢復協程return 0;
}

輸出:

Start of coroutine
End of coroutine

4.?三向比較 (Spaceship Operator?<=>)

C++20 引入了“太空船操作符” (<=>),也叫做三向比較操作符,它提供了一種簡化的方式來執行比較操作,如?<<===>>=

示例:
#include <iostream>struct Point {int x, y;auto operator<=>(const Point&) const = default;  // 默認生成比較操作符
};int main() {Point p1 = {1, 2}, p2 = {2, 3};if (p1 < p2) {std::cout << "p1 is less than p2\n";}return 0;
}

輸出:

p1 is less than p2

5.?模塊 (Modules)

C++20 引入了模塊的概念,這是對頭文件的替代。模塊可以提高編譯速度,避免頭文件帶來的重復處理和依賴問題。模塊支持?import?語句來替代傳統的?#include

示例:

假設我們有一個模塊?math

// math.cppm - 模塊定義文件
export module math;
export int add(int a, int b) { return a + b; }

然后在主程序中導入該模塊:

// main.cpp
import math;int main() {int result = add(3, 4);std::cout << result << std::endl;  // 輸出 7return 0;
}

注意:模塊在許多編譯器中仍處于實驗階段,需要啟用特定的編譯器選項。

6.?范圍循環 (Range-based for loop with initializer)

C++20 增強了范圍 for 循環,允許在循環中初始化變量。

示例:
#include <iostream>
#include <vector>int main() {std::vector<int> nums = {1, 2, 3, 4};for (auto&& [index, value] : nums) {  // 使用結構化綁定std::cout << "Value: " << value << std::endl;}return 0;
}

輸出:

Value: 1
Value: 2
Value: 3
Value: 4

7.?std::span

std::span?是 C++20 新增的一個輕量級的視圖容器,它可以用來表示一個數組的連續區間。它與傳統的指針數組相比,更加安全,并支持對數組進行邊界檢查。

示例:
#include <iostream>
#include <span>void printSpan(std::span<int> sp) {for (auto val : sp) {std::cout << val << " ";}
}int main() {int arr[] = {1, 2, 3, 4, 5};printSpan(arr);  // 使用 std::span 傳遞數組return 0;
}

輸出:

1 2 3 4 5 

8.?consteval?和?constinit

C++20 引入了?consteval?和?constinit?關鍵字:

  • consteval?用于指定一個函數必須在編譯時求值。
  • constinit?用于確保某個變量在初始化時是常量。
示例:
#include <iostream>consteval int square(int n) { return n * n; }int main() {constexpr int result = square(5);  // 在編譯時計算std::cout << result << std::endl;  // 輸出 25return 0;
}

輸出:

25

總結

C++20 引入了許多強大的新特性,極大增強了 C++ 的表達能力和編程效率。它使得編寫更現代、更安全和更高效的 C++ 代碼變得更加容易。例如,概念和協程提高了代碼的可讀性和可維護性,而模塊的引入可以顯著提高編譯性能。掌握 C++20 的特性將有助于編寫更清晰、強大和高效的 C++ 代碼。

10.?C++ 2023: C++23

  • 新特性和小幅增強:
    • **擴展的?std::ranges**:提供更多的支持與增強,使得 C++ 的標準庫更具表達力和功能。
      • 改進的協程支持:協程功能得到進一步加強,增加了更多的靈活性和優化。
    • 更好的標準化和規范:提高了 C++ 語言和標準庫的易用性和性能。

C++23(正式名稱為 C++23)是C++語言的最新標準,作為C++20和C++17之后的下一代標準,C++23在語言特性、庫功能和編譯器優化等方面引入了一些重要的改進。以下是C++23中的一些新特性和代碼示例。

1.?改進的常量表達式(constexpr

C++23擴展了constexpr的功能,允許更多復雜的功能在編譯時執行。例如,C++23允許在constexpr函數中使用try-catch語句,這在之前的標準中是無法實現的。

示例:
constexpr int safe_divide(int a, int b) {if (b == 0) throw std::invalid_argument("Division by zero");return a / b;
}int main() {constexpr int result = safe_divide(10, 2);  // 編譯時執行return 0;
}

2.?std::expected

C++23引入了std::expected,它是一個可以用來表示函數調用結果的類型,類似于std::optional,但是它包含了錯誤信息。這個特性非常適合替代try-catch塊來進行錯誤處理,尤其是在函數返回時希望包含更多的錯誤信息時。

示例:
#include <expected>
#include <iostream>std::expected<int, std::string> divide(int a, int b) {if (b == 0) {return std::unexpected("Division by zero");}return a / b;
}int main() {auto result = divide(10, 0);if (result) {std::cout << "Result: " << *result << std::endl;} else {std::cout << "Error: " << result.error() << std::endl;}return 0;
}

3.?范圍(Ranges)庫增強

C++20引入了范圍(Ranges)庫,C++23在此基礎上進行了增強。新增了更豐富的算法和視圖,使得在進行集合操作時,代碼更加簡潔且易于理解。

示例:
#include <ranges>
#include <vector>
#include <iostream>int main() {std::vector<int> v = {1, 2, 3, 4, 5};// 使用ranges庫處理集合auto result = v | std::views::transform([](int n) { return n * n; })| std::views::filter([](int n) { return n > 10; });for (int i : result) {std::cout << i << " ";}return 0;
}

4.?std::format?改進

C++20引入了?std::format?來格式化字符串,C++23對其進行了進一步改進。新增了更多的格式化選項,以及對各種類型的支持。

示例:
#include <format>
#include <iostream>int main() {int age = 25;std::string name = "Alice";std::string formatted = std::format("Name: {}, Age: {}", name, age);std::cout << formatted << std::endl;return 0;
}

5.?explicit?改進

C++23擴展了explicit關鍵字,可以用于更加靈活的構造函數,使其適應更復雜的類型轉換需求。

示例:
struct A {explicit A(int x) {}  // 顯式構造函數
};struct B {explicit B(A a) {}  // 顯式構造函數
};int main() {A a(1);B b(a);  // 需要顯示構造A對象的參數return 0;
}

6.?std::span?支持的改進

std::span?是C++20中引入的用于表示數組片段的類,C++23對其進行了擴展,支持了更多的功能。

示例:
#include <span>
#include <iostream>void print_span(std::span<int> s) {for (auto elem : s) {std::cout << elem << " ";}
}int main() {int arr[] = {1, 2, 3, 4, 5};std::span<int> sp(arr, 3);  // 只傳遞數組的前3個元素print_span(sp);return 0;
}

7.?新的屬性([[likely]]?和?[[unlikely]]

C++23引入了?[[likely]]?和?[[unlikely]]?屬性,用于給編譯器提供分支預測的提示,幫助優化代碼。

示例:
#include <iostream>int main() {bool condition = true;if ([[likely]] condition) {std::cout << "Condition is likely true" << std::endl;} else {std::cout << "Condition is unlikely true" << std::endl;}return 0;
}

總結

C++23增強了語言的表達能力和效率,提供了更多的編程便利性,尤其在常量表達式、錯誤處理、范圍操作、字符串格式化和編譯時優化方面有顯著的提升。這些特性使得C++更加現代化,代碼更加簡潔易懂,同時也帶來了更高效的執行性能。

這些新特性和API增強為開發者提供了更加靈活和強大的工具,可以讓代碼更加高效、易維護并且更具可讀性。


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

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

相關文章

LeetCode 21. 合并兩個有序鏈表(Python)

將兩個升序鏈表合并為一個新的 升序 鏈表并返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 輸入&#xff1a;l1 [1,2,4], l2 [1,3,4] 輸出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 輸入&#xff1a;l1 [], l2 [] 輸出&#xff1a;[] 示例 3&#xff1a; 輸…

FPGA 配置原理

用戶編程控制的FPGA 是通過加載比特位流配置內部的存儲單元實現的。該存儲單元就是所謂的配置單元&#xff0c;它必須在器件上電后進行配置&#xff0c;從而設置查找表&#xff08;LUT&#xff09;的屬性、連線方式、IOB 電壓標準和其它的用戶設計。 1.配置幀 以Xilinx 公司的…

測試人員如何更好的跟蹤BUG

軟件測試中BUG跟蹤是確保軟件質量的關鍵環節。測試人員不僅需要發現BUG&#xff0c;還需有效管理其狀態&#xff0c;從報告到修復驗證的全過程。如何更好地跟蹤BUG&#xff0c;成為測試人員提升效率的重要課題。本文將詳細探討測試人員可以采用的策略&#xff0c;包括使用工具、…

lamp平臺介紹

一、lamp介紹 網站&#xff1a; 靜態 動態 php語言 .php 作用&#xff1a;運行php語言編寫動態網站應用 lamp Linux Apache MySQL PHP PHP是作為httpd的一個功能模塊存在的 二、部署lamp平臺 1、測試httpd是否可正常返回PHP的響應 2、測試PHP代碼是否可正常連接數據…

2025年滲透測試面試題總結-字某跳動-滲透測試實習生(題目+回答)

網絡安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 字某跳動-滲透測試實習生 滲透流程信息收集如何處理子域名爆破中的泛解析問題繞過CDN尋找真實IPPHPINFO頁面關注…

Spring Boot 自動裝配深度解析與實踐指南

目錄 引言&#xff1a;自動裝配如何重塑Java應用開發&#xff1f; 一、自動裝配核心機制 1.1 自動裝配三大要素 1.2 自動裝配流程 二、自定義自動配置實現 2.1 創建自動配置類 2.2 配置屬性綁定 2.3 注冊自動配置 三、條件注解深度應用 3.1 常用條件注解對比 3.2 自定…

《算法筆記》9.6小節 數據結構專題(2)并查集 問題 C: How Many Tables

題目描述 Today is Ignatius birthday. He invites a lot of friends. Now its dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to stay with stra…

CPU、SOC、MPU、MCU--詳細分析四者的區別

一、CPU 與SOC的區別 1.CPU 對于電腦&#xff0c;我們經常提到&#xff0c;處理器&#xff0c;內存&#xff0c;顯卡&#xff0c;硬盤四大部分可以組成一個基本的電腦。其中的處理器——Central Processing Unit&#xff08;中央處理器&#xff09;。CPU是一臺計算機的運算核…

Linux常用指令學習筆記

文章目錄 前言一、文件和目錄操作指令1. 文件操作2. 目錄操作 二、文件權限管理三、網絡相關指令四、系統管理指令五、文本編輯器基本操作 六、壓縮和解壓指令七、總結 前言 在當今的IT領域&#xff0c;Linux系統因其開源、穩定、安全等特性&#xff0c;廣泛應用于服務器、個人…

android studio通過 jni 調用第三方非標準 so庫

調用第三方的so方法&#xff0c;但這個so內的方法不是標準的jni方法。這就需要我們自己寫jni然后鏈接到第三方so庫&#xff0c;通過jni調用so庫中的方法。 1.簡述&#xff1a; 要先有第三方的so庫.so文件和編譯庫對應的.h頭文件 我們自己用 c/c 創建一個標準的so 庫,比如 my…

Spring(三)容器-注入

一 自動注入Autowire 代碼實現&#xff1a; package org.example.spring01.service;import org.springframework.stereotype.Service;Service public class UserService {}package org.example.spring01.controller;import lombok.Data; import lombok.ToString; import org.…

mac上最好的Python開發環境之Anaconda+Pycharm

為了運行修改 label-studio項目源碼&#xff0c;又不想在windows上運行&#xff0c;便在mac上開始安裝&#xff0c;開始使用poetry安裝&#xff0c;各種報錯&#xff0c;不是zip包解壓不了&#xff0c;就是numpy編譯報錯&#xff0c;pipy.org訪問出錯。最后使用anaconda成功啟動…

IDEA 接入 Deepseek

在本篇文章中&#xff0c;我們將詳細介紹如何在 JetBrains IDEA 中使用 Continue 插件接入 DeepSeek&#xff0c;讓你的 AI 編程助手更智能&#xff0c;提高開發效率。 一、前置準備 在開始之前&#xff0c;請確保你已經具備以下條件&#xff1a; 安裝了 JetBrains IDEA&…

前綴和矩陣

前綴和矩陣&#xff08;Prefix Sum Matrix&#xff09;是一種預處理技術&#xff0c;用于快速計算二維矩陣中任意子矩陣的元素和。其核心思想是通過提前計算并存儲每個位置左上角所有元素的和&#xff0c;將子矩陣和的查詢時間從暴力計算的 (O(mn)) 優化到 (O(1))。以下是構建前…

系統架構評估中的重要概念

(1)敏感點(Sensitivity Point) 和權衡點 (Tradeoff Point)。敏感點和權衡點是關鍵的架構 決策。敏感點是一個或多個構件(和/或構件之間的關系)的特性。研究敏感點可使設計人員 或分析員明確在搞清楚如何實現質量目標時應注意什么。權衡點是影響多個質量屬性的特性&#xff0c; …

SSL證書和HTTPS:全面解析它們的功能與重要性

每當我們在互聯網上輸入個人信息、進行在線交易時&#xff0c;背后是否有一個安全的保障&#xff1f;這時&#xff0c;SSL證書和HTTPS便扮演了至關重要的角色。本文將全面分析SSL證書和HTTPS的含義、功能、重要性以及它們在網絡安全中的作用。 一、SSL證書的定義與基本概念 S…

基于微信小程序的停車場管理系統的設計與實現

第1章 緒論 1.1 課題背景 隨著移動互聯形式的不斷發展&#xff0c;各行各業都在摸索移動互聯對本行業的改變&#xff0c;不斷的嘗試開發出適合于本行業或者本公司的APP。但是這樣一來用戶的手機上就需要安裝各種軟件&#xff0c;但是APP作為一個只為某個公司服務的一個軟件&a…

寶塔找不到php擴展swoole,服務器編譯安裝

1. 在php7.4中安裝swoole&#xff0c;但找不到這個擴展安裝 2. 服務器下載源碼解壓安裝 http://pecl.php.net/package/swoole 下載4.8.0版本 解壓到/www/server/php/74/下 3. 發現報錯問題&#xff1b; 更新一下依賴 yum update yum -y install gcc gcc-c autoconf libjpe…

大數據測試總結

總結測試要點&#xff1a; 參考產品文檔&#xff0c;技術文檔梳理以下內容 需求來源 業務方應用場景 數據源&#xff0c;數據格轉&#xff0c;數據產出&#xff0c;數據呈現方式&#xff08;數據消亡史&#xff09;&#xff0c;數據量級&#xff08;增量&#xff0c;全量&am…

React封裝通用Table組件,支持搜索(多條件)、篩選、自動序號、數據量統計等功能。未采用二次封裝調整靈活,包含使用文檔

封裝通用組件 一、封裝思想二、react代碼三、css代碼四、實現效果五、使用文檔 BasicTableModal 表格模態框組件1.組件簡介2.功能特點3.使用方法基礎用法寬度控制示例帶篩選功能搜索功能示例自定義單元格渲染 4.API 說明PropsColumn 配置項Filter 配置項 5.注意事項 一、封裝思…