STL源碼剖析 內存基本處理工具 初始化空間的五個函數

  • 初始化空間的五個函數
  • 構造函數 construct()
  • 析構函數 destroy()
  • 剩余三個底層函數 和?高層函數之間的對應關系如下
  • uninitialized_copy()? 對應 copy()
  • uninitialized_fill()? 對應 fill()
  • uninitialized_fill_n()? 對應 fill_n()
  • 使用<memory>使用上述三個底層函數

uninitialized_copy()

template<class InputIterator,class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result);
  • uninitialized_copy() 將內存的配置和對象的構造行為分離開來
  • 如果指向的輸出區域[result ,result+(last - first)] 內的每一個迭代器都指向的是未經初始化的區域,那么uninitialized_copy()會使用copy constructor,給身為輸入來源的[first , last] 范圍內的每一個對象產生一個復制品,放到輸出范圍內
  • 針對輸入范圍內的每一個迭代器i 使用construct(&*(result + (i-first)),*i) 產生*i的復制品,放置到輸出范圍的相對位置上

容器的全局間構造函數 通過兩個步驟完成

  • 配置內存塊? 足以包含范圍內的所有元素
  • 使用uninitialized_copy()在這個范圍上構造元素

注意事項

  • 原子性;commit or rollback
  • 要不給所有元素都全部執行構造函數,要不不構造任何東西,必須析構已經產生的所有元素
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就會有效
//如果是POD型別 執行的流程就會跳轉到以下函數,這個是通過function template的參數推導機制得到的
template<class InputIterator,class ForwardIterator>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,true_type){return copy(first,last,result);//調用STL算法 copy()
}
//如果不是POD型別 執行的流程就會轉向以下函數  這個是通過function template的參數推導機制得到的
template<class InputIterator,class ForwardIterator>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,false_type){ForwardIterator cur = result;//為了簡化 省略了異常處理for(; first!=last;++first,++cur){Chy::_allocate(&*cur,*first);}return cur;
}//函數的邏輯是
//首先萃取出 迭代器first的value type,然后判斷這個型別是否是POD類型
template<class InputIterator,class ForwardIterator,class T>
inline ForwardIterator __uninitizlized_copy(ForwardIterator first,ForwardIterator last,ForwardIterator result,T*){//以下使用的是__type_traits<T1>::is_POD_type is _PODtypedef typename __type_traits<T>::is_POD_type is_POD;return (__uninitialized_copy_aux(first,last,result,is_POD()));
}/** 迭代器first指向的是 輸入端的起始位置* 迭代器last指向的是 輸入端的結束位置* 迭代器result指向的是 輸出端的(初始化)的起始位置*/
template<class InputIterator,class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result){}//針對 char* 和wchar*兩種型別 采用最有效率的做法 memmove(直接移動內存內存執行復制的行為)
//偏特化設計
//針對const char*的特化版本inline char* uninitialized_copy(const char* first,const char* last,char* result){memmove(result,first,last-first);return result+(last - first);
}//針對const wchar_t *的特化版本
inline wchar_t* uninitialized_copy(const wchar_t* first,const wchar_t* last,wchar_t* result){memmove(result,first,sizeof(wchar_t)*(last - first));return result + (last - first);
}

uninitialized_fill()

template<class ForwardIterator,class T>
ForwardIterator uninitialized_fill(ForwardIterator first,ForwardIterator last,const T&x);
  • uninitialized_fill() 將內存的配置和對象的構造行為分離開來
  • 如果指向的輸出區域[first,last] 內的每一個迭代器都指向的是未經初始化的區域,那么uninitialized_fill()會在這個范圍內產生x(上述第三個參數的復制品)
  • 即uninitialized_fill()會針對[first,last]范圍內的每個迭代器i 調用construct(&*i,x),在i所指定的地方產生i的復制品。

注意事項

  • 原子性;commit or rollback
  • 要不給所有元素都全部執行構造函數,要不不構造任何東西,必須析構已經產生的所有元素
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就會有效
//如果是POD型別 執行的流程就會跳轉到以下函數,這個是通過function template的參數推導機制得到的
template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,true_type){fill(first,last,x);//調用STL算法 fill()
}
//如果不是POD型別 執行的流程就會轉向以下函數  這個是通過function template的參數推導機制得到的
template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,false_type){ForwardIterator cur = first;//為了簡化 省略了異常處理for(;cur != last;++cur){Chy::_construct(&*cur,x);}
}template<class ForwardIterator,class T,class T1>
inline void __uninitialized_fill(ForwardIterator first,ForwardIterator last,const T&x,T1*){typedef typename __type_traits<T1>::is_POD_type is_POD;__uninitialized_fill_aux(first,last,x,is_POD());
}/** 迭代器first指向輸出端 (欲初始化空間) 起始處* 迭代器last指向的輸出端 (欲初始化空間) 結尾處 前閉后開區間* x 表示初始數值*/
template<class ForwardIterator,class T>
ForwardIterator uninitialized_fill(ForwardIterator first,ForwardIterator last,const T&x){__uninitialized_fill(first,last,x,value_type(first));
}

uninitialized_fill_n()

template<class ForwardIterator,class Size,class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,const T&x);
  • uninitialized_fill_n() 將內存的配置和對象的構造行為分離開來
  • 如果指向的輸出區域[first,first+n] 內的每一個迭代器都指向的是未經初始化的區域,那么uninitialized_fill()會在這個范圍內產生x(上述第三個參數的復制品)
  • 即uninitialized_fill()會針對[first,last]范圍內的每個迭代器i 調用construct(&*i,x),在i所指定的地方產生i的復制品。
  • 原子性;commit or rollback
  • 要不給所有元素都全部執行構造函數,要不不構造任何東西,必須析構已經產生的所有元素

補充

  • POD類型是指 Plain Old Data,也就是標量類型或者傳統的C struct型別
  • POD類型 必然具備trivial ctor/dtor/copy/assignment函數
  • 因此對于POD型別采用最有效率的初值填寫手法,對于non POD型別采取最保險安全的做法
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就會有效
//如果是POD型別 執行的流程就會跳轉到以下函數,這個是通過function template的參數推導機制得到的
template<class ForwardIterator,class Size,class T>
inline ForwardIterator __uninitizlized_fill_n_aux(ForwardIterator first,Size n,const T&x){return fill_n(first,n,x); //交給高階函數執行
}//如果不是POD型別 執行的流程就會轉向以下函數  這個是通過function template的參數推導機制得到的
template<class ForwardIterator,class Size,class T>
inline ForwardIterator __uninitizlized_fill_n_aux(ForwardIterator first,Size n,const T&x,false_type){ForwardIterator cur = first;//為了簡化 省略了異常處理for( ; n>0 ; --n,++cur){Chy::_allocate(&*cur,x);}return cur;
}//函數的邏輯是
//首先萃取出 迭代器first的value type,然后判斷這個型別是否是POD類型
template<class ForwardIterator,class Size,class T,class T1>
inline ForwardIterator __uninitizlized_fill_n(ForwardIterator first,Size n,const T&x,T1*){//以下使用的是__type_traits<T1>::is_POD_type is _PODtypedef typename __type_traits<T1>::is_POD_type is_POD;return __uninitizlized_fill_n_aux(first,n,x,is_POD());
}template<class ForwardIterator,class Size,class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,const T&x){return __uninitizlized_fill_n(first,n,x,value_type(first));//使用value_type()判斷first的value type
}

參考鏈接

  • C++ STL __type_traits解析 - 知乎

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

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

相關文章

單基因gsea_篩到5分的核心基因以后你可以怎么做?

這一次我們從一些已經發表的文章拆解&#xff0c;我們來看看&#xff0c;你找到了一個核心基因以后&#xff0c;你可以怎么做呢&#xff1f;我們就不說那么多廢話了&#xff0c;直接用幾篇文章的解讀來帶著大家領會一下如何去進行下一步的分析。Case1&#xff1a;預后標志物免疫…

安卓 原生okhttp使用get與post獲取網絡數據

網址 https://square.github.io/okhttp/ 配置 依賴 在module的build.gradle中&#xff1a; implementation com.squareup.okhttp3:okhttp:3.14.7implementation com.squareup.okio:okio:1.17.5AndroidManifest.xml <uses-permission android:name"android.permissi…

STL源碼剖析 迭代器的概念和traits編程技法

迭代器&#xff1a;依序巡防某個聚合物(容器)所含的各個元素&#xff0c;但是不需要暴露這個聚合物的內部表述方式核心思想&#xff1a;將容器和算法分開&#xff0c;彼此獨立設計容器和算法的泛型化&#xff0c;均可以使用模板&#xff0c;使用迭代器連接容器和算法例子 templ…

.sql文件如何執行_干貨|一條SQL查詢語句是如何執行的

作者&#xff1a;wanber鏈接&#xff1a;https://blog.nowcoder.net/n/9e120e8f1314466bb44fe706b283dc20

STL源碼剖析 5中迭代器型別

最常使用的5種迭代器的型別 為 value_type、difference_type、pointer、reference、iterator_category。如果想要自己開發的容器和STL進行適配&#xff0c;就需要定義上述5種類型 iteraor_traits 必須針對傳入的型別為 pointer 或者 pointer-to-const設計偏特化版本 template &…

Python學習16 正則表達式3 練習題

用戶名匹配 1.用戶名匹配&#xff1a;由數字、大小寫字母、下劃線_、中橫線-組成&#xff0c;長度為6-12位&#xff0c;不能以數字開頭。 import re usernameab578_-SDF resultre.search(^[a-zA-Z_-][0-9a-zA-Z_-]{5,12}$,username) print(result)郵箱 2.驗證輸入的郵箱&…

加載tf模型 正確率很低_深度學習模型訓練全流程!

↑↑↑關注后"星標"Datawhale每日干貨 & 每月組隊學習&#xff0c;不錯過Datawhale干貨 作者&#xff1a;黃星源、奉現&#xff0c;Datawhale優秀學習者本文從構建數據驗證集、模型訓練、模型加載和模型調參四個部分對深度學習中模型訓練的全流程進行講解。一個成…

Python學習17 Turtle庫繪圖

學習網址&#xff1a;https://docs.python.org/zh-cn/3/library/turtle.html Turtle庫 Turtle庫是Python語言中一個很流行的繪制圖像的函數庫&#xff0c;一個小烏龜&#xff0c;在一個橫軸為x、縱軸為y的坐標系原點&#xff08;畫布中心&#xff09;&#xff0c;(0,0)位置開…

android ros 節點編寫_嵌入式的我們為什么要學ROS

前言本來是要寫一篇STM32移植ROS的一個小lib庫&#xff0c;ROS一般都是需要跑在Linux上的&#xff0c;STM32使用就是當成一個ROS通訊的小節點&#xff0c;但是寫文章時間不夠&#xff0c;所以就簡單做一篇ROS的介紹文章&#xff0c;分享給嵌入式的小伙伴們。ROS現在在機器人領域…

STL源碼剖析 __type_traits

traits編程 彌補了C本身的不足STL只對迭代器進行規范制定出了iterator_traits&#xff0c;SGI在此基礎上進一步擴展&#xff0c;產生了__type_traits雙下劃線的含義是這個是SGI內部使用的東西&#xff0c;不屬于STL標準iterator_traits 負責萃取迭代器的特性__type_traits負責萃…

java 學生成績

題目 對學生成績大于60分的&#xff0c;輸出“合格”。低于60分的&#xff0c;輸出“不合格” 代碼 使用/除法簡化代碼 package l1_switch_case;import java.util.Scanner;public class SwitchDemo2 {public static void main(String[] args) {Scanner scanner new Scanne…

STL源碼剖析 序列式容器|Vector

容器的概觀和分類 array 數組 、list 鏈表、tree樹 、stack堆棧、queue隊列、hash table散列表、set集合、map映射表根據數據在容器中的排列順序&#xff0c;將上述數據結構分為序列式和關聯式兩種類型SGI STL使用內縮方式來表達基層和衍生層之間的關系衍生不是派生&#xff0…

ansible 修改文件變量_Ansible Playbook中的變量與引用

Ansible是一個系列文章&#xff0c;我會盡量以通俗易懂、詼諧幽默的總結方式給大家呈現這些枯燥的知識點&#xff0c;讓學習變的有趣一些。Ansible自動化運維前言前面有說到使用playbook來搞一些復雜的功能&#xff0c;我們使用YAML來寫playbook&#xff0c;就像我們用其它語言…

java 判斷日期為第幾天

題目1 編寫程序&#xff1a;從鍵盤上輸入2019年的“month”和“day”&#xff0c;要求通過程序 輸出輸入的日期為2019年的第幾天。 代碼1 從12月往下加日期數 package l1_switch_case; import java.util.Scanner; public class SwitchDemo4 {public static void main(Strin…

STL源碼剖析 list概述

目錄 list的節點(node) list迭代器 list 的構造和內存管理 list 的元素操作 list相較于vector連續的線性空間就顯得很復雜&#xff0c;他的存儲空間是不連續的&#xff0c;好處是每次插入和刪除一個元素的時候&#xff0c;只需要配置或者釋放一個元素的空間 插入和刪除十分的…

vsftp不允許切換到其它目錄_IntelliJ IDEA如何對project的目錄進行篩選顯示?

如果你的項目很龐大&#xff0c;同一個功能用到的各種文件散落在多個文件夾&#xff0c;開發時切換不便&#xff0c;可以利用scope功能&#xff0c;只顯示該功能用到的文件&#xff0c;讓project列表十分清爽&#xff0c;提高開發效率。本文使用的IDEA版本為2020.1。1、打開sco…

java 年份對應的中國生肖

題目 編寫一個程序&#xff0c;為一個給定的年份找出其對應的中國生肖。 中國的生肖基于12年一個周期&#xff0c; 每年用一個動物代表&#xff1a; rat、ox、tiger、rabbit、dragon、snake、horse、sheep、monkey、 rooster、dog、pig。 提示&#xff1a;2019年&#xff1a;豬…

密碼學專題 對稱加密算法

一般來說&#xff0c;使用OpenSSL對稱加密算法有兩種方式&#xff0c;一種是使用API函數的方式&#xff0c;一種是使用OpenSSL提供的對稱加密算法指令方式。本書將介紹對稱加密算法的指令方式OpenSSL的對稱加密算法指令主要用來對數據進行加密和解密處理&#xff0c;輸入輸出的…

網絡防火墻單向和雙向_單向晶閘管與雙向晶閘管之間的不同之處

晶閘管是回一個可以控導點開關&#xff0c;能以弱電去控制強電的各種電路。晶閘管常用于整流&#xff0c;調壓&#xff0c;交直流變化&#xff0c;開關&#xff0c;調光等控制電路中。具有提交小&#xff0c;重量輕&#xff0c;耐壓高&#xff0c;容量大&#xff0c;效率高&…

java 遍歷100以內的偶數,偶數的和,偶數的個數

題目 遍歷100以內的偶數&#xff0c;偶數的和&#xff0c;偶數的個數 代碼 package l2_for; /*遍歷100以內的偶數&#xff0c;偶數的和&#xff0c;偶數的個數*/ public class ForDemo1 {public static void main(String[] args) {//方法1&#xff1a;int sum1 0,count10;f…