std::chrono類的簡單使用實例及分析


author: hjjdebug
date: 2025年 05月 20日 星期二 14:36:17 CST
descrip: std::chrono類的簡單使用實例及分析


文章目錄

  • 1.實例代碼:
  • 2. 代碼分析:
    • 2.1 auto t1 = std::chrono::high_resolution_clock::now();
      • 2.1.1 什么是 system_clock
      • 2.1.2 什么是 chrono::time_point?
      • 2.1.3 什么是duration?
        • 2.1.3.1 duration 的一個實例
      • 2.1.4 這么多的內涵,到底怎樣理解time_point呢?
      • 2.1.5 time_point t1 在gdb中的表示
    • 2.2 auto delta_t = t2 - t1;
    • 2.3 auto dur_obj = std::chrono::duration<double, std::milli>(delta_t);
      • 2.3.1 duration 對象能夠知道數值代表的是毫秒,納秒或者其它單位嗎?

1.實例代碼:

$ cat main.cpp
#include <iostream>
#include <unistd.h> //for sleep
#include <chrono>
using namespace std;int main() {//now()是類的靜態函數, auto t1 = std::chrono::high_resolution_clock::now(); //t1 是time_point 對象, time_point 對象是什么?// 被測代碼sleep(1);auto t2 = std::chrono::high_resolution_clock::now();  // 返回的是時間點對象auto delta_t = t2 - t1; //2個time_point 對象相減,肯定被重構了. 返回的是 duration 對象, duration 對象是什么?auto dur_obj = std::chrono::duration<double, std::milli>(delta_t); //構造函數,參數是duration對象,返回ms為單位的duration對象std::cout << "耗時:" << dur_obj.count() << "ms" <<endl; //訪問其數值,通過count(), 我們構建的是ms為單位的對象,所以單位就是msdur_obj = std::chrono::duration<double, std::milli>(500); //另一個構造函數,給500就打印500,單位還是ms,由std::milli類型決定的.std::cout << "測試打印:" << dur_obj.count() << "ms" <<endl;return 0;
}

執行結果
$ ./temp
耗時:1000.14ms
測試打印:500ms

代碼很短,可是內涵很豐富. 是c++模板類的入門之路.
下面幾乎是逐句分析了.

2. 代碼分析:

2.1 auto t1 = std::chrono::high_resolution_clock::now();

std: namespace
chrono: namespace
大命名空間下的小命名空間,此時的命名空間為std::chrono
using high_resolution_clock = system_clock;
using 與typedef 類似, 也與#define 有可比性. 就是說high_resolution_clock 這個類型
是 system_clock 類型的小名, 它們是一個類型. 由此引出 system_clock 類型

2.1.1 什么是 system_clock

    struct system_clock{ //定義了一堆類型別名, 告訴編譯器說, 別慌, 有一堆類型記住它們的小名.typedef chrono::nanoseconds duration; //使用ns做durationtypedef duration::rep rep;typedef duration::period period;typedef chrono::time_point<system_clock, duration> time_point;//靜態變量是屬于類的變量, 是全局的.static constexpr bool is_steady = false;//靜態函數是屬于類的函數. 恰似普通的函數, 執行不使用this指針,有3個//成員函數 now() to_time_t(time_point &t), from_time_t(std::time_t t)static time_point now() noexcept;static std::time_tto_time_t(const time_point& __t) noexcept{return std::time_t(duration_cast<chrono::seconds>(__t.time_since_epoch()).count());}static time_pointfrom_time_t(std::time_t __t) noexcept{typedef chrono::time_point<system_clock, seconds> __from;return time_point_cast<system_clock::duration>(__from(chrono::seconds(__t)));}};

now 是system_clock 類的靜態成員函數, 返回一個time_point 類型對象

2.1.2 什么是 chrono::time_point?

看一下它的聲明,
template<class Clock, class Duration = typename Clock::duration> class time_point;
它是一個類模板. 有兩個類型參數.
時鐘類型決定了時間的來源, 有system_clock, steady_clock,high_resolution_clock(是system_clock的代名詞)

system_clock, 前面已經有交代.
劇透一下 system_clock 的紀元為 1970-01-01 00:00:00 UTC), unix時間戳起點
system_clock是time_point類模板的第一個參數.

time_point類模板的第二個參數類型duration 是什么?

2.1.3 什么是duration?

duration 是一個類型,這里先給duration的一個實例.

2.1.3.1 duration 的一個實例
(gdb) ptype dur_obj
type = struct std::chrono::duration<double, std::ratio<1, 1000> > [with _Rep = double, _Period = std::ratio<1, 1000>] {private:_Rep __r;public:duration(void);duration(const std::chrono::duration<_Rep, _Period> &);~duration();std::chrono::duration<_Rep, _Period> & operator=(const std::chrono::duration<_Rep, _Period> &);_Rep count(void) const;std::chrono::duration<_Rep, _Period> operator+(void) const;std::chrono::duration<_Rep, _Period> operator-(void) const;std::chrono::duration<_Rep, _Period> & operator++(void);std::chrono::duration<_Rep, _Period> operator++(int);std::chrono::duration<_Rep, _Period> & operator--(void);std::chrono::duration<_Rep, _Period> operator--(int);std::chrono::duration<_Rep, _Period> & operator+=(const std::chrono::duration<_Rep, _Period> &);std::chrono::duration<_Rep, _Period> & operator-=(const std::chrono::duration<_Rep, _Period> &);std::chrono::duration<_Rep, _Period> & operator*=(const _Rep &);std::chrono::duration<_Rep, _Period> & operator/=(const _Rep &);static std::chrono::duration<_Rep, _Period> zero(void);static std::chrono::duration<_Rep, _Period> min(void);static std::chrono::duration<_Rep, _Period> max(void);void duration<int>(const int &);void duration<double>(const _Rep &);void duration<long, std::ratio<1, 1000000000> >(const std::chrono::duration<long, std::ratio<1, 1000000000> > &);typedef _Rep rep;
}

它有一個私有成員變量 _Rep __r, __Rep 是represent的簡寫, 是類模板的第一個類型參數.可能是double或long
類模板還有第2個類型參數, 此處是 std::ratio<1,1000> 類型, 這個類型起碼有2個類屬性可以使用
std::ratio<1,1000>::num=1
std::ratio<1,1000>::den=1000
至于其它構造,析構,重載運算符就不具體分析了.

2.1.4 這么多的內涵,到底怎樣理解time_point呢?

時間點對象timepoint是時間點類模板用system_clock 和 nanoseconds 為類型參數實例化后的一個對象.它有一個duration類型的變量記錄其屬性
其值說明是從 1970-01-01 00:00:00 開始的 納秒數, 用long int 表示的數

2.1.5 time_point t1 在gdb中的表示

time_point 包含一個duration 對象 __d, duration對象包含一個實現類型(long或double)變量 __r
(gdb) p t1
$1 = {
__d = {
__r = 1747640811095678930 //1970-01-01 00:00:00開始的時間, 單位僅從對象本身是看不出來的.
}
}
//從類模板類型參數上知道它是ns, 但模板類型參數僅僅是編譯期屬性, 編譯期知道它是ns, 但運行期就不知道了.

(gdb) ptype t1 , 
type = struct std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1, 1000000000> > > [with _Clock = std::chrono::_V2::system_clock, _Dur = std::chrono::duration<long, std::ratio<1, 1000000000> >] {private:_Dur __d;  //私有成員變量, duration 類型public:time_point(void);time_point(const _Dur &);_Dur time_since_epoch(void) const;std::chrono::time_point<_Clock, _Dur> & operator+=(const _Dur &);std::chrono::time_point<_Clock, _Dur> & operator-=(const _Dur &);static std::chrono::time_point<_Clock, _Dur> min(void);static std::chrono::time_point<_Clock, _Dur> max(void);typedef _Dur duration;
}(gdb) p t2
$2 = {__d = {__r = 1747640813823889979 //unix 時間點到現在的時間間隔}
}

2.2 auto delta_t = t2 - t1;

//兩個時間點之差是duration 變量
//2個time_point 對象相減,運算被重構了. 返回的是 duration 對象
(gdb) p delta_t //一種duration 對象
$3 = {
__r = 2728211049
}
(gdb) p dur_obj //另一種duration 對象
$4 = {
__r = 2728.211049
}

2.3 auto dur_obj = std::chrono::duration<double, std::milli>(delta_t);

代碼分析:
std::chrono namespace
duration<double, std::milli>: 是一個實例化模板類
std::chrono::duration<double,std::milli>(delta_t);
類名稱后面跟上一個參數(這里是duration為參數)就是構建對象的過程(copy構造)
auto dur_obj = std::chrono::duration<double, std::milli>(delta_t); (賦值構造)
把一個無名對象賦值給一個有名對象 dur_obj

duration 對象是什么?數值代表了什么意思?
請參考2.1.4 說明duration 對象是什么類型

2.3.1 duration 對象能夠知道數值代表的是毫秒,納秒或者其它單位嗎?

答: 對于一個duration 對象
$4 = {
__r = 2728.211049
}
duration 本身并不知道數值代表的是ms,ns或其它單位.
但是duration類卻能夠根據構造函數傳來的類型及模板參使用的類型對傳來的數值進行轉換.
這是靜態編譯的能力.
現在已經計算出了這個值并付給了對象的成員. 但這個對象已經不知道自己是什么單位了,
因為對象本身沒有保留單位信息. 即單位信息做為模板類型參數不是運行期特性只是編譯期特性.

那我們怎么知道數值的單位是什么呢?
這是你自己的問題, 你自己根據數值的轉變過程確定它應該是什么單位.

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

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

相關文章

電子電路仿真實驗教學平臺重磅上線!——深圳航天科技創新研究院傾力打造,助力高校教學數字化轉型

在傳統電子電路課堂中&#xff0c;實驗室的燈光總與高昂的成本、擁擠的設備、反復的耗材損耗相伴&#xff0c;而教師不得不面對這樣的現實&#xff1a;有限的硬件資源束縛著教學深度&#xff0c;不可逆的實驗風險制約著創新探索&#xff0c;固化的時空場景阻礙著個性化學習。當…

面試真題 - 高并發場景下Nginx如何優化

Nginx是一款高性能的Web服務器和反向代理服務器&#xff0c;以其輕量級、高并發處理能力和穩定性聞名。在面對高并發場景時&#xff0c;合理的配置與優化策略至關重要&#xff0c;以確保服務的穩定性和響應速度。 以下是針對Nginx進行高并發優化的一些關鍵配置和策略&#xff…

算法與數據結構:質數、互質判定和裴蜀定理

文章目錄 質數質數判定質數篩選質因數分解互質判定裴蜀定理 質數 首先回顧「質數」的定義&#xff1a;若一個正整數無法被除了 1 ?和它自身之外的任何自然數整除&#xff0c;則稱該數為質數&#xff08;或素數&#xff09;&#xff0c;否則稱該正整數為合數。 根據上述定義&…

代碼隨想錄算法訓練營第60期第四十二天打卡

大家好&#xff0c;今天還是繼續我們的動態規劃里面的背包問題&#xff0c;前面我們主要接觸的是0-1背包和完全背包&#xff0c;其實這兩個背包問題主要就是看看每一件物品我們是否有多件&#xff0c;如果每一件物品我們只能取一次的話那這樣我們就是0-1背包&#xff0c;如果每…

第41天-Python+Qt四屏播放器開發指南

一、技術選型與工具準備 核心庫: Pyqt5:Python標準GUI庫,構建用戶界面 os / sys:文件系統操作 開發環境: pip install pyqt5 最終效果與運行 import sys from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout # 添加缺失的布局管理器 from PyQt5.QtCore impor…

upload-labs通關筆記-第12關 文件上傳之白名單GET法

目錄 一、白名單過濾 二、%00截斷 1、%00截斷原理 2、空字符 3、截斷條件 &#xff08;1&#xff09;PHP版本 < 5.3.4 &#xff08;2&#xff09;magic_quotes_gpc配置為Off &#xff08;3&#xff09;代碼邏輯存在缺陷 三、源碼分析 1、代碼審計 &#xff08;1&…

Node.js數據抓取技術實戰示例

Node.js常用的庫有哪些呢&#xff1f;比如axios或者node-fetch用來發送HTTP請求&#xff0c;cheerio用來解析HTML&#xff0c;如果是動態網頁的話可能需要puppeteer這樣的無頭瀏覽器。這些工具的組合應該能滿足大部分需求。 然后&#xff0c;可能遇到的難點在哪里&#xff1f;…

數據結構(3)線性表-鏈表-單鏈表

我們學習過順序表時&#xff0c;一旦對頭部或中間的數據進行處理&#xff0c;由于物理結構的連續性&#xff0c;為了不覆蓋&#xff0c;都得移&#xff0c;就導致時間復雜度為O&#xff08;n&#xff09;&#xff0c;還有一個潛在的問題就是擴容&#xff0c;假如我們擴容前是10…

【Unity】DOTween的常用函數解釋

DOTween插件常用函數解釋 1.DOTween.To&#xff08;通用變化動畫&#xff09; 解釋&#xff1a;將某一個值在一定的時間內變化到另一個值&#xff08;通用的函數&#xff09;&#xff0c;可用于大部分的動畫變化 使用示例&#xff1a; using UnityEngine; using DG.Tweenin…

數據結構測試模擬題(1)

1、約瑟夫問題 #include<bits/stdc.h> using namespace std; const int N25; int e[N],ne[N],head-1,idx1; int n,m; void add_to_head(int x){e[idx]x;ne[idx]head;headidx; } void add(int k,int x){e[idx]x;ne[idx]ne[k];ne[k]idx; } int main(){cin>>n>>…

Helm配置之為特定Deployment配置特定Docker倉庫(覆蓋全局配置)

文章目錄 Helm配置之為特定Deployment配置特定Docker倉庫(覆蓋全局配置)需求方法1:使用Helm覆蓋值方法2: 在Lens中臨時修改Deployment配置步驟 1: 創建 Docker Registry Secret步驟 2: 在 Deployment 中引用 Secret參考資料Helm配置之為特定Deployment配置特定Docker倉庫(覆…

BERT 作為Transformer的Encoder 為什么采用可學習的位置編碼

摘要 BERT 在位置編碼上與原始 Transformer 論文中的 sin/cos 公式不同&#xff0c;選擇了可學習&#xff08;learned&#xff09;的位置嵌入方案。本文將從 Transformer 原始位置編碼選項入手&#xff0c;分析 BERT 選擇 learned positional embeddings 的四大核心原因&#x…

【Linux 學習計劃】-- gcc、g++、動靜態庫鏈接

目錄 什么是gcc、g gcc、g 相關操作詳解 預處理、編譯、匯編、鏈接來源 動靜態鏈接是什么 結語 什么是gcc、g gcc、g其實就是編譯器&#xff0c;是幫助我們從.c或者.cc&#xff0c;.cpp文件編譯成可執行程序的 其中&#xff0c;我們如果要編譯c語言文件的話&#xff0c;…

前端讀取本地項目中 public/a.xlsx 文件中的數據 vue3

前端讀取本地項目中 public/a.xlsx 文件中的數據 vue3 項目中需要在 Vue3 項目中讀取 public/a.xlsx 文件&#xff0c;可以使用 fetch API 來獲取文件內容 一、安裝 xlsx 首先&#xff0c;你需要安裝 xlsx 庫&#xff1a; npm install xlsx二、在需要用的頁面里引入xlsx im…

MySQL:to many connections連接數過多

當你遇到 MySQL: Too many connections 錯誤時&#xff0c;意味著當前連接數已達到 MySQL 配置的最大限制。這通常是由于并發連接過多或連接未正確關閉導致的。 一、查看當前連接數 查看 MySQL 當前允許的最大連接數 SHOW VARIABLES LIKE max_connections;查看當前使用的最大…

2024年熱門AI趨勢及回顧

人工智能的崛起 2024 年可能會被銘記為人工智能不再是一種技術新奇事物&#xff0c;而是成為現實的一年。微軟、Salesforce 和 Intuit 等巨頭將人工智能融入主流企業解決方案&#xff1b;從文案寫作到數據分析&#xff0c;專門的人工智能應用程序和服務如雨后春筍般涌現&#…

LangFlow技術深度解析:可視化編排LangChain應用的新范式 -(2)流編輯器系統

Flow Editor System | langflow-ai/langflow | DeepWiki 流編輯器系統 相關源文件 流編輯器系統是 Langflow 的核心交互式組件&#xff0c;允許用戶直觀地創建、編輯和管理 LLM 驅動的應用程序。它提供了一個直觀的畫布&#xff0c;用戶可以在其中添加節點、將其與邊緣連接并…

驅動-定時-秒-字符設備

文章目錄 目的相關資料參考實驗驅動程序-timer_dev.c編譯文件-Makefile測試程序-timer.c分析 加載驅動-運行測試程序總結 目的 通過定時器timer_list、字符設備、規避競爭關系-原子操作&#xff0c;綜合運用 實現一個程序&#xff0c;加深之前知識的理解。 實現字符設備驅動框…

[Java實戰]Spring Boot整合Kafka:高吞吐量消息系統實戰(二十七)

[Java實戰]Spring Boot整合Kafka&#xff1a;高吞吐量消息系統實戰&#xff08;二十七&#xff09; 一、引言 Apache Kafka作為一款高吞吐量、低延遲的分布式消息隊列系統&#xff0c;廣泛應用于實時數據處理、日志收集和事件驅動架構。結合Spring Boot的自動化配置能力&…

Kotlin Multiplatform--04:經驗總結(持續更新)

Kotlin Multiplatform--04&#xff1a;經驗總結&#xff08;持續更新&#xff09; 引言 引言 本章用來記載筆者開發過程中的一些經驗總結 一、Ktor設置Header 在官方文檔中&#xff0c;想要設置Header的示例代碼如下&#xff1a; client.get("https://ktor.io&qu…