溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C++11有什么新特性

發(fā)布時間:2021-10-29 16:34:13 來源:億速云 閱讀:156 作者:iii 欄目:編程語言

這篇文章主要介紹“C++11有什么新特性”,在日常操作中,相信很多人在C++11有什么新特性問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C++11有什么新特性”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

auto & decltype

關(guān)于C++11新特性,最先提到的肯定是類型推導(dǎo),C++11引入了auto和decltype關(guān)鍵字,使用他們可以在編譯期就推導(dǎo)出變量或者表達式的類型,方便開發(fā)者編碼也簡化了代碼。

  •  auto:讓編譯器在編譯器就推導(dǎo)出變量的類型,可以通過=右邊的類型推導(dǎo)出變量的類型。

auto a = 10; // 10是int型,可以自動推導(dǎo)出a是int
  •  decltype:相對于auto用于推導(dǎo)變量類型,而decltype則用于推導(dǎo)表達式類型,這里只用于編譯器分析表達式的類型,表達式實際不會進行運算。 

cont int &i = 1;  int a = 2;  decltype(i) b = 2; // b是const int&

關(guān)于auto和decltype的詳細介紹請看:一文吃透C++11中auto和decltype知識點

左值右值

眾所周知C++11新增了右值引用,這里涉及到很多概念:

  •  左值:可以取地址并且有名字的東西就是左值。

  •  右值:不能取地址的沒有名字的東西就是右值。

  •  純右值:運算表達式產(chǎn)生的臨時變量、不和對象關(guān)聯(lián)的原始字面量、非引用返回的臨時變量、lambda表達式等都是純右值。

  •  將亡值:可以理解為即將要銷毀的值。

  •  左值引用:對左值進行引用的類型。

  •  右值引用:對右值進行引用的類型。

  •  移動語義:轉(zhuǎn)移資源所有權(quán),類似于轉(zhuǎn)讓或者資源竊取的意思,對于那塊資源,轉(zhuǎn)為自己所擁有,別人不再擁有也不會再使用。

  •  完美轉(zhuǎn)發(fā):可以寫一個接受任意實參的函數(shù)模板,并轉(zhuǎn)發(fā)到其它函數(shù),目標函數(shù)會收到與轉(zhuǎn)發(fā)函數(shù)完全相同的實參。

  •  返回值優(yōu)化:當函數(shù)需要返回一個對象實例時候,就會創(chuàng)建一個臨時對象并通過復(fù)制構(gòu)造函數(shù)將目標對象復(fù)制到臨時對象,這里有復(fù)制構(gòu)造函數(shù)和析構(gòu)函數(shù)會被多余的調(diào)用到,有代價,而通過返回值優(yōu)化,C++標準允許省略調(diào)用這些復(fù)制構(gòu)造函數(shù)。

這里的詳細介紹請看:左值引用、右值引用、移動語義、完美轉(zhuǎn)發(fā),你知道的不知道的都在這里

列表初始化

在C++11中可以直接在變量名后面加上初始化列表來進行對象的初始化,詳細介紹一定要看這篇文章:學(xué)會C++11列表初始化

std::function & std::bind & lambda表達式

c++11新增了std::function、std::bind、lambda表達式等封裝使函數(shù)調(diào)用更加方便,詳細介紹請看:搞定c++11新特性std::function和lambda表達式

模板的改進

C++11關(guān)于模板有一些細節(jié)的改進:

  •  模板的右尖括號

  •  模板的別名

  •  函數(shù)模板的默認模板參數(shù)

詳細介紹請看:C++11的模板改進

并發(fā)

c++11關(guān)于并發(fā)引入了好多好東西,有:

  •  std::thread相關(guān)

  •  std::mutex相關(guān)

  •  std::lock相關(guān)

  •  std::atomic相關(guān)

  •  std::call_once相關(guān)

  •  volatile相關(guān)

  •  std::condition_variable相關(guān)

  •  std::future相關(guān)

  •  async相關(guān)

詳細介紹請看:c++11新特性之線程相關(guān)所有知識點

這里也使用c++11來實現(xiàn)的線程池和定時器,可以看:

C++線程池的實現(xiàn)之格式修訂版

C++定時器的實現(xiàn)之格式修訂版

智能指針

很多人談到c++,說它特別難,可能有一部分就是因為c++的內(nèi)存管理吧,不像java那樣有虛擬機動態(tài)的管理內(nèi)存,在程序運行過程中可能就會出現(xiàn)內(nèi)存泄漏,然而這種問題其實都可以通過c++11引入的智能指針來解決,相反我還認為這種內(nèi)存管理還是c++語言的優(yōu)勢,因為盡在掌握。

c++11引入了三種智能指針:

  •  std::shared_ptr

  •  std::weak_ptr

  •  std::unique_ptr

詳細介紹請看:c++11新特性之智能指針

基于范圍的for循環(huán)

直接看代碼

vector<int> vec;  for (auto iter = vec.begin(); iter != vec.end(); iter++) { // before c++11     cout << *iter << endl;  }  for (int i : vec) { // c++11基于范圍的for循環(huán)  cout << "i" << endl;  }

委托構(gòu)造函數(shù)

委托構(gòu)造函數(shù)允許在同一個類中一個構(gòu)造函數(shù)調(diào)用另外一個構(gòu)造函數(shù),可以在變量初始化時簡化操作,通過代碼來感受下委托構(gòu)造函數(shù)的妙處吧:

不使用委托構(gòu)造函數(shù):

struct A {     A(){}     A(int a) { aa_ = a; }     A(int a, int b) { // 好麻煩         aa_ = a;         bb_ = b;    }     A(int a, int b, int c) { // 好麻煩         aa_ = a;         bb_ = b;         cc_ = c;    }     int a_;    int b_;     int c_;  };

使用委托構(gòu)造函數(shù):

struct A {     A(){}     A(int a) { aa_ = a; }     A(int a, int b) : A(a) { bb_ = b; }     A(int a, int b, int c) : A(a, b) { cc_ = c; }     int a_;     int b_;     int c_;  };

初始化變量是不是方便了許多。

繼承構(gòu)造函數(shù)

繼承構(gòu)造函數(shù)可以讓派生類直接使用基類的構(gòu)造函數(shù),如果有一個派生類,我們希望派生類采用和基類一樣的構(gòu)造方式,可以直接使用基類的構(gòu)造函數(shù),而不是再重新寫一遍構(gòu)造函數(shù),老規(guī)矩,看代碼:

不使用繼承構(gòu)造函數(shù):

struct Base {     Base() {}     Base(int a) { aa_ = a; }     Base(int a, int b) : Base(a) { bb_ = b; }     Base(int a, int b, int c) : Base(a, b) { cc_ = c; }     int a_;     int b_;     int c_;  };  struct Derived : Base {     Derived() {}     Derived(int a) : Base(a) {} // 好麻煩     Derived(int a, int b) : Base(a, b) {} // 好麻煩     Derived(int a, int b, int c) : Base(a, b, c) {} // 好麻煩  };  int main() {     Derived a(1, 2, 3);     return 0;  }

使用繼承構(gòu)造函數(shù):

struct Base {     Base() {}     Base(int a) { aa_ = a; }     Base(int a, int b) : Base(a) { bb_ = b; }     Base(int a, int b, int c) : Base(a, b) { cc_ = c; }     int a_;     int b_;     int c_;  };  struct Derived : Base {     using Base::Base;  };  int main() {     Derived a(1, 2, 3);     return 0;  }

只需要使用using Base::Base繼承構(gòu)造函數(shù),就免去了很多重寫代碼的麻煩。

nullptr

nullptr是c++11用來表示空指針新引入的常量值,在c++中如果表示空指針語義時建議使用nullptr而不要使用NULL,因為NULL本質(zhì)上是個int型的0,其實不是個指針。舉例:

void func(void *ptr) {     cout << "func ptr" << endl;  }  void func(int i) {     cout << "func i" << endl;  }  int main() {     func(NULL); // 編譯失敗,會產(chǎn)生二義性     func(nullptr); // 輸出func ptr     return 0;  }

final & override

c++11關(guān)于繼承新增了兩個關(guān)鍵字,final用于修飾一個類,表示禁止該類進一步派生和虛函數(shù)的進一步重載,override用于修飾派生類中的成員函數(shù),標明該函數(shù)重寫了基類函數(shù),如果一個函數(shù)聲明了override但父類卻沒有這個虛函數(shù),編譯報錯,使用override關(guān)鍵字可以避免開發(fā)者在重寫基類函數(shù)時無意產(chǎn)生的錯誤。

示例代碼1:

struct Base {     virtual void func() {         cout << "base" << endl;    }  };  struct Derived : public Base{     void func() override { // 確保func被重寫         cout << "derived" << endl;    }     void fu() override { // error,基類沒有fu(),不可以被重寫        }  };

示例代碼2:

struct Base final {     virtual void func() {         cout << "base" << endl;    }  };  struct Derived : public Base{ // 編譯失敗,final修飾的類不可以被繼承     void func() override {         cout << "derived" << endl;    }  };

default

c++11引入default特性,多數(shù)時候用于聲明構(gòu)造函數(shù)為默認構(gòu)造函數(shù),如果類中有了自定義的構(gòu)造函數(shù),編譯器就不會隱式生成默認構(gòu)造函數(shù),如下代碼:

struct A {     int a;     A(int i) { a = i; }  };  int main() {     A a; // 編譯出錯     return 0;  }

上面代碼編譯出錯,因為沒有匹配的構(gòu)造函數(shù),因為編譯器沒有生成默認構(gòu)造函數(shù),而通過default,程序員只需在函數(shù)聲明后加上“=default;”,就可將該函數(shù)聲明為 defaulted 函數(shù),編譯器將為顯式聲明的 defaulted 函數(shù)自動生成函數(shù)體,如下:

struct A {     A() = default;     int a;     A(int i) { a = i; }  };  int main() {     A a;     return 0;  }

編譯通過。

delete

c++中,如果開發(fā)人員沒有定義特殊成員函數(shù),那么編譯器在需要特殊成員函數(shù)時候會隱式自動生成一個默認的特殊成員函數(shù),例如拷貝構(gòu)造函數(shù)或者拷貝賦值操作符,如下代碼:

struct A {     A() = default;     int a;     A(int i) { a = i; }  };  int main() {     A a1;     A a2 = a1;  // 正確,調(diào)用編譯器隱式生成的默認拷貝構(gòu)造函數(shù)     A a3;     a3 = a1;  // 正確,調(diào)用編譯器隱式生成的默認拷貝賦值操作符  }

而我們有時候想禁止對象的拷貝與賦值,可以使用delete修飾,如下:

struct A {     A() = default;     A(const A&) = delete;     A& operator=(const A&) = delete;     int a;     A(int i) { a = i; }  };  int main() {     A a1;     A a2 = a1;  // 錯誤,拷貝構(gòu)造函數(shù)被禁用     A a3;     a3 = a1;  // 錯誤,拷貝賦值操作符被禁用  }

delele函數(shù)在c++11中很常用,std::unique_ptr就是通過delete修飾來禁止對象的拷貝的。

explicit

explicit專用于修飾構(gòu)造函數(shù),表示只能顯式構(gòu)造,不可以被隱式轉(zhuǎn)換,根據(jù)代碼看explicit的作用:

不用explicit:

struct A {     A(int value) { // 沒有explicit關(guān)鍵字         cout << "value" << endl;    }  };  int main() {     A a = 1; // 可以隱式轉(zhuǎn)換     return 0;  }

使用explicit:

struct A {     explicit A(int value) {         cout << "value" << endl;    }  };  int main() {     A a = 1; // error,不可以隱式轉(zhuǎn)換     A aa(2); // ok     return 0;  }

const

因為要講后面的constexpr,所以這里簡單介紹下const。

const字面意思為只讀,可用于定義變量,表示變量是只讀的,不可以更改,如果更改,編譯期間就會報錯。

主要用法如下:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2.  用于定義常量,const的修飾的變量不可更改。

const int value = 5;

    2.  指針也可以使用const,這里有個小技巧,從右向左讀,即可知道const究竟修飾的是指針還是指針所指向的內(nèi)容。

char *const ptr; // 指針本身是常量  const char* ptr; // 指針指向的變量為常量

    3.  在函數(shù)參數(shù)中使用const,一般會傳遞類對象時會傳遞一個const的引用或者指針,這樣可以避免對象的拷貝,也可以防止對象被修改。

class A{};  void func(const A& a);

    4.  const修飾類的成員變量,表示是成員常量,不能被修改,可以在初始化列表中被賦值。

class A {  const int value = 5;  };  class B {  const int value;  B(int v) : value(v){}  };

    5.  修飾類成員函數(shù),表示在該函數(shù)內(nèi)不可以修改該類的成員變量。

class A{  void func() const;  };

    6.  修飾類對象,類對象只能調(diào)用該對象的const成員函數(shù)。

class A {  void func() const;  };  const A a;  a.func();

constexpr

constexpr是c++11新引入的關(guān)鍵字,用于編譯時的常量和常量函數(shù),這里直接介紹constexpr和const的區(qū)別:

兩者都代表可讀,const只表示read only的語義,只保證了運行時不可以被修改,但它修飾的仍然有可能是個動態(tài)變量,而constexpr修飾的才是真正的常量,它會在編譯期間就會被計算出來,整個運行過程中都不可以被改變,constexpr可以用于修飾函數(shù),這個函數(shù)的返回值會盡可能在編譯期間被計算出來當作一個常量,但是如果編譯期間此函數(shù)不能被計算出來,那它就會當作一個普通函數(shù)被處理。如下代碼:

#include<iostream>  using namespace std;  constexpr int func(int i) {     return i + 1;  }  int main() {    int i = 2;     func(i);// 普通函數(shù)     func(2);// 編譯期間就會被計算出來  }

enum class

c++11新增有作用域的枚舉類型,看代碼

不帶作用域的枚舉代碼:

enum AColor {     kRed,     kGreen,     kBlue  };  enum BColor {     kWhite,     kBlack,     kYellow  };  int main() {     if (kRed == kWhite) {         cout << "red == white" << endl;    }     return 0;  }

如上代碼,不帶作用域的枚舉類型可以自動轉(zhuǎn)換成整形,且不同的枚舉可以相互比較,代碼中的紅色居然可以和白色比較,這都是潛在的難以調(diào)試的bug,而這種完全可以通過有作用域的枚舉來規(guī)避。

有作用域的枚舉代碼:

enum class AColor {     kRed,     kGreen,     kBlue  };  enum class BColor {     kWhite,     kBlack,     kYellow  };  int main() {     if (AColor::kRed == BColor::kWhite) { // 編譯失敗         cout << "red == white" << endl;    }     return 0;  }

使用帶有作用域的枚舉類型后,對不同的枚舉進行比較會導(dǎo)致編譯失敗,消除潛在bug,同時帶作用域的枚舉類型可以選擇底層類型,默認是int,可以改成char等別的類型。

enum class AColor : char {     kRed,    kGreen,     kBlue };

我們平時編程過程中使用枚舉,一定要使用有作用域的枚舉取代傳統(tǒng)的枚舉。

非受限聯(lián)合體

c++11之前union中數(shù)據(jù)成員的類型不允許有非POD類型,而這個限制在c++11被取消,允許數(shù)據(jù)成員類型有非POD類型,看代碼:

struct A {     int a;     int *b;  };  union U {     A a; // 非POD類型 c++11之前不可以這樣定義聯(lián)合體     int b;  };

對于什么是POD類型,大家可以自行查下資料,大體上可以理解為對象可以直接memcpy的類型。

sizeof

c++11中sizeof可以用的類的數(shù)據(jù)成員上,看代碼:

c++11前:

struct A {     int data[10];     int a;  };  int main() {     A a;     cout << "size " << sizeof(a.data) << endl;     return 0;  }

c++11后:

struct A {     int data[10];     int a;  };  int main() {     cout << "size " << sizeof(A::data) << endl;     return 0;  }

想知道類中數(shù)據(jù)成員的大小在c++11中是不是方便了許多,而不需要定義一個對象,在計算對象的成員大小。

assertion

static_assert(true/false, message);

c++11引入static_assert聲明,用于在編譯期間檢查,如果第一個參數(shù)值為false,則打印message,編譯失敗。

自定義字面量

c++11可以自定義字面量,我們平時c++中都或多或少使用過chrono中的時間,例如:

std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 100ms  std::this_thread::sleep_for(std::chrono::seconds(100)); // 100s

其實沒必要這么麻煩,也可以這么寫:

std::this_thread::sleep_for(100ms); // c++14里可以這么使用,這里只是舉個自定義字面量使用的例子  std::this_thread::sleep_for(100s);

這就是自定義字面量的使用,示例如下:

struct mytype {     unsigned long long value;  };  constexpr mytype operator"" _mytype ( unsigned long long n ) {     return mytype{n};  }  mytype mm = 123_mytype;  cout << mm.value << endl;

關(guān)于自定義字面量,可以看下chrono的源代碼,相信大家會有很大收獲,需要源碼分析chrono的話,可以留言給我。

內(nèi)存對齊

什么是內(nèi)存對齊

理論上計算機對于任何變量的訪問都可以從任意位置開始,然而實際上系統(tǒng)會對這些變量的存放地址有限制,通常將變量首地址設(shè)為某個數(shù)N的倍數(shù),這就是內(nèi)存對齊。

為什么要內(nèi)存對齊

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2.  硬件平臺限制,內(nèi)存以字節(jié)為單位,不同硬件平臺不一定支持任何內(nèi)存地址的存取,一般可能以雙字節(jié)、4字節(jié)等為單位存取內(nèi)存,為了保證處理器正確存取數(shù)據(jù),需要進行內(nèi)存對齊。

  3.  提高CPU內(nèi)存訪問速度,一般處理器的內(nèi)存存取粒度都是N的整數(shù)倍,假如訪問N大小的數(shù)據(jù),沒有進行內(nèi)存對齊,有可能就需要兩次訪問才可以讀取出數(shù)據(jù),而進行內(nèi)存對齊可以一次性把數(shù)據(jù)全部讀取出來,提高效率。

在c++11之前如果想創(chuàng)建內(nèi)存對齊需要:

void align_cpp11_before()  {     static char data[sizeof(void *) + sizeof(A)];    const uintptr_t kAlign = sizeof(void *) - 1;     char *align_ptr =         reinterpret_cast<char *>(reinterpret_cast<uintptr_t>(data + kAlign) & ~kAlign);     A *attr = new (align_ptr) A;  }

c++11關(guān)于內(nèi)存對齊新增了一些函數(shù):

void align_cpp11_after()  {    static std::aligned_storage<sizeof(A),                                 alignof(A)>::type data;     A *attr = new (&data) A;  }

還有:alignof()、std::alignment_of()、alignas(),關(guān)于內(nèi)存對齊詳情可以看這篇文章:內(nèi)存對齊之格式修訂版

thread_local

c++11引入thread_local,用thread_local修飾的變量具有thread周期,每一個線程都擁有并只擁有一個該變量的獨立實例,一般用于需要保證線程安全的函數(shù)中。

#include <iostream>  #include <thread>  class A {    public:     A() {}     ~A() {}     void test(const std::string &name) {         thread_local int count = 0;         ++count;         std::cout << name << ": " << count << std::endl;    }  }; void func(const std::string &name) {     A a1;     a1.test(name);     a1.test(name);     A a2;     a2.test(name);     a2.test(name);  }  int main() {     std::thread(func, "thread1").join();     std::thread(func, "thread2").join();     return 0;  }

輸出:

thread1: 1  thread1: 2  thread1: 3  thread1: 4  thread2: 1  thread2: 2  thread2: 3  thread2: 4

驗證上述說法,對于一個線程私有變量,一個線程擁有且只擁有一個該實例,類似于static。

基礎(chǔ)數(shù)值類型

c++11新增了幾種數(shù)據(jù)類型:long long、char16_t、char32_t等

隨機數(shù)功能

c++11關(guān)于隨機數(shù)功能則較之前豐富了很多,典型的可以選擇概率分布類型,先看如下代碼:

#include <time.h>  #include <iostream>  #include <random>  using namespace std;  int main() {     std::default_random_engine random(time(nullptr));     std::uniform_int_distribution<int> int_dis(0, 100); // 整數(shù)均勻分布     std::uniform_real_distribution<float> real_dis(0.0, 1.0); // 浮點數(shù)均勻分布     for (int i = 0; i < 10; ++i) {         cout << int_dis(random) << ' ';    }     cout << endl;     for (int i = 0; i < 10; ++i) {         cout << real_dis(random) << ' ';    }     cout << endl;     return 0;  }

輸出:

38 100 93 7 66 0 68 99 41 7  0.232202 0.617716 0.959241 0.970859 0.230406 0.430682 0.477359 0.971858 0.0171148 0.64863

代碼中舉例的是整數(shù)均勻分布和浮點數(shù)均勻分布,c++11提供的概率分布類型還有好多,例如伯努利分布、正態(tài)分布等,具體可以見最后的參考資料。

正則表達式

c++11引入了regex庫更好的支持正則表達式,見代碼:

#include <iostream>  #include <iterator>  #include <regex>  #include <string>  int main() {     std::string s = "I know, I'll use2 regular expressions.";  // 忽略大小寫     std::regex self_regex("REGULAR EXPRESSIONS", std::regex_constants::icase);     if (std::regex_search(s, self_regex)) {         std::cout << "Text contains the phrase 'regular expressions'\n";    }     std::regex word_regex("(\\w+)");  // 匹配字母數(shù)字等字符     auto words_begin = std::sregex_iterator(s.begin(), s.end(), word_regex);     auto words_end = std::sregex_iterator();     std::cout << "Found " << std::distance(words_begin, words_end) << " words\n";     const int N = 6;     std::cout << "Words longer than " << N << " characters:\n";     for (std::sregex_iterator i = words_begin; i != words_end; ++i) {         std::smatch match = *i;         std::string matchmatch_str = match.str();         if (match_str.size() > N) {             std::cout << " " << match_str << '\n';        }    }     std::regex long_word_regex("(\\w{7,})");     // 超過7個字符的單詞用[]包圍     std::string new_s = std::regex_replace(s, long_word_regex, "[$&]");     std::cout << new_s << '\n';  }

chrono

c++11關(guān)于時間引入了chrono庫,源于boost,功能強大,chrono主要有三個點:

  •  duration

  •  time_point

  •  clocks

duration

std::chrono::duration表示一段時間,常見的單位有s、ms等,示例代碼:

// 拿休眠一段時間舉例,這里表示休眠100ms  std::this_thread::sleep_for(std::chrono::milliseconds(100));

sleep_for里面其實就是std::chrono::duration,表示一段時間,實際是這樣:

typedef duration<int64_t, milli> milliseconds;  typedef duration<int64_t> seconds;

duration具體模板如下:

1 template <class Rep, class Period = ratio<1> > class duration;

Rep表示一種數(shù)值類型,用來表示Period的數(shù)量,比如int、float、double,Period是ratio類型,用來表示【用秒表示的時間單位】比如second,常用的duration<Rep, Period>已經(jīng)定義好了,在std::chrono::duration下:

  •  ratio<3600, 1>:hours

  •  ratio<60, 1>:minutes

  •  ratio<1, 1>:seconds

  •  ratio<1, 1000>:microseconds

  •  ratio<1, 1000000>:microseconds

  •  ratio<1, 1000000000>:nanosecons

ratio的具體模板如下:

template <intmax_t N, intmax_t D = 1> class ratio;

N代表分子,D代表分母,所以ratio表示一個分數(shù),我們可以自定義Period,比如ratio<2, 1>表示單位時間是2秒。

time_point

表示一個具體時間點,如2020年5月10日10點10分10秒,拿獲取當前時間舉例:

std::chrono::time_point<std::chrono::high_resolution_clock> Now() {     return std::chrono::high_resolution_clock::now();  }  // std::chrono::high_resolution_clock為高精度時鐘,下面會提到

clocks

時鐘,chrono里面提供了三種時鐘:

  •  steady_clock

  •  system_clock

  •  high_resolution_clock

steady_clock

穩(wěn)定的時間間隔,表示相對時間,相對于系統(tǒng)開機啟動的時間,無論系統(tǒng)時間如何被更改,后一次調(diào)用now()肯定比前一次調(diào)用now()的數(shù)值大,可用于計時。

system_clock

表示當前的系統(tǒng)時鐘,可以用于獲取當前時間:

int main() {     using std::chrono::system_clock;     system_clock::time_point today = system_clock::now();     std::time_t tt = system_clock::to_time_t(today);     std::cout << "today is: " << ctime(&tt);     return 0;  }  // today is: Sun May 10 09:48:36 2020

high_resolution_clock

high_resolution_clock表示系統(tǒng)可用的最高精度的時鐘,實際上就是system_clock或者steady_clock其中一種的定義,官方?jīng)]有說明具體是哪個,不同系統(tǒng)可能不一樣,我之前看gcc chrono源碼中high_resolution_clock是steady_clock的typedef。

更多關(guān)于chrono的介紹可以看下我之前的文章:RAII妙用之計算函數(shù)耗時

新增數(shù)據(jù)結(jié)構(gòu)

  •  std::forward_list:單向鏈表,只可以前進,在特定場景下使用,相比于std::list節(jié)省了內(nèi)存,提高了性能 

std::forward_list<int> fl = {1, 2, 3, 4, 5};  for (const auto &elem : fl) {     cout << elem;  }
  •  std::unordered_set:基于hash表實現(xiàn)的set,內(nèi)部不會排序,使用方法和set類似

  •  std::unordered_map:基于hash表實現(xiàn)的map,內(nèi)部不會排序,使用方法和set類似

  •  std::array:數(shù)組,在越界訪問時拋出異常,建議使用std::array替代普通的數(shù)組

  •  std::tuple:元組類型,類似pair,但比pair擴展性好 

typedef std::tuple<int, double, int, double> Mytuple;  Mytuple t(0, 1, 2, 3);  std::cout << "0 " << std::get<0>(t);  std::cout << "1 " << std::get<1>(t);  std::cout << "2 " << std::get<2>(t);  std::cout << "3 " << std::get<3>(t);

新增算法

  •  all_of:檢測表達式是否對范圍[first, last)中所有元素都返回true,如果都滿足,則返回true 

std::vector<int> v(10, 2);  if (std::all_of(v.cbegin(), v.cend(), [](int i) { return i % 2 == 0; })) {  std::cout << "All numbers are even\n";  }
  •  any_of:檢測表達式是否對范圍[first, last)中至少一個元素返回true,如果滿足,則返回true,否則返回false,用法和上面一樣

  •  none_of:檢測表達式是否對范圍[first, last)中所有元素都不返回true,如果都不滿足,則返回true,否則返回false,用法和上面一樣

  •  find_if_not:找到第一個不符合要求的元素迭代器,和find_if相反

  •  copy_if:復(fù)制滿足條件的元素

  •  itoa:對容器內(nèi)的元素按序遞增 

std::vector<int> l(10);  std::iota(l.begin(), l.end(), 19); // 19為初始值  for (auto n : l) std::cout << n << ' ';  // 19 20 21 22 23 24 25 26 27 28
  •  minmax_element:返回容器內(nèi)最大元素和最小元素位置 

int main() {     std::vector<int> v = {3, 9, 1, 4, 2, 5, 9};     auto result = std::minmax_element(v.begin(), v.end());     std::cout << "min element at: " << *(result.first) << '\n';     std::cout << "max element at: " << *(result.second) << '\n';     return 0;  }  // min element at: 1 // max element at: 9
  •  is_sorted、is_sorted_until:返回容器內(nèi)元素是否已經(jīng)排好序。

到此,關(guān)于“C++11有什么新特性”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI