最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 時間庫duration 類的原理與復(fù)現(xiàn)(最新整理)

 更新時間:2025年07月16日 10:28:43   作者:行行宜行行  
本文解析了C++11 chrono庫中duration類的實(shí)現(xiàn)原理,基于ratio模板實(shí)現(xiàn)時間間隔的類型化表示,通過編譯期計(jì)算和類型安全設(shè)計(jì)支持靈活的時間單位轉(zhuǎn)換與算術(shù)運(yùn)算,對比了標(biāo)準(zhǔn)庫與自定義實(shí)現(xiàn)的差異,強(qiáng)調(diào)了模板元編程在時間處理中的優(yōu)勢,感興趣的朋友一起看看吧

C++ 時間庫實(shí)現(xiàn):duration 類的原理與復(fù)現(xiàn)解析

在現(xiàn)代編程中,時間處理是一個常見且重要的需求。C++11 標(biāo)準(zhǔn)庫引入了 <chrono> 頭文件,提供了一套處理時間的工具,其中 duration 類是時間表示的核心組件之一。在上一篇文章中,分析和復(fù)現(xiàn)了 <ratio>, 本文將基于 ratio 深入解析 duration 類的實(shí)現(xiàn)原理,并詳細(xì)介紹筆者自己復(fù)現(xiàn)這一功能強(qiáng)大的時間間隔表示類的完整過程。

duration 類的基本概念

duration 類模板用于表示時間間隔,它以模板參數(shù)的形式定義了兩個關(guān)鍵要素:

  • Rep_:表示時間間隔的數(shù)值類型(如 int64_t
  • Period_:表示時間間隔的單位(通過 ratio 模板定義)

這種設(shè)計(jì)使得 duration 能夠靈活處理不同精度和單位的時間間隔,從納秒到天數(shù)都能統(tǒng)一表示和操作。標(biāo)準(zhǔn)庫中通過特化 ratio 模板定義了常見的時間單位:

  • 納秒:nano = ratio<1, 1000000000>
  • 微秒:micro = ratio<1, 1000000>
  • 毫秒:milli = ratio<1, 1000>
  • 秒:ratio<1>
  • 分鐘:ratio<60>
  • 小時:ratio<3600>
  • 天:ratio<86400>

duration 類的核心實(shí)現(xiàn)原理

1. 模板參數(shù)設(shè)計(jì)

duration 類的模板定義如下:

template<typename Rep_, typename Period_ = ratio<1>>
class duration;
  • Rep_:存儲時間間隔的具體數(shù)值,通常為整數(shù)類型(如 int64_t
  • Period_:時間單位,基于 ratio 模板實(shí)現(xiàn),默認(rèn)單位為秒

采用參數(shù)化設(shè)計(jì)使得 duration 具有高度的靈活性和類型安全性,不同單位的 duration 是不同的類型,避免了隱式類型轉(zhuǎn)換帶來的錯誤。

2. 單位轉(zhuǎn)換的核心:duration_cast

duration_cast 函數(shù)是實(shí)現(xiàn)不同時間單位轉(zhuǎn)換的關(guān)鍵,其核心邏輯如下:

 /// 用于將一個時間段從一個周期單位轉(zhuǎn)換到另一個周期單位
    template<typename ToDuration_, typename Rep_, typename Period_>
    constexpr ToDuration_ duration_cast(const duration<Rep_, Period_> &d__) {
        using CF = ratio_divide<Period_, typename ToDuration_::period>;
        /// 類型轉(zhuǎn)換(整型除法,可能發(fā)生截?cái)啵?
        auto r_ = static_cast<typename ToDuration_::rep>(
                static_cast<long long>(d__.count()) * CF::num / CF::den
        );
        return ToDuration_(r_);
    }
  • 通過 ratio_divide 計(jì)算兩個時間單位的轉(zhuǎn)換因子(時間轉(zhuǎn)換因子用于在不同時間單位或者系統(tǒng)之間進(jìn)行轉(zhuǎn)換,計(jì)算的原理和場景是強(qiáng)相關(guān)的)
  • 使用編譯期計(jì)算的 CF::numCF::den 完成單位轉(zhuǎn)換,分別代表源單位與目標(biāo)單位的比例關(guān)系中的分子部分與分母部分
  • 利用 static_cast 進(jìn)行安全的類型轉(zhuǎn)換

通過這種分子/分母的組合實(shí)現(xiàn)方式確保了單位轉(zhuǎn)換在編譯期完成,既保證了運(yùn)行時的效率,同時又避免了浮點(diǎn)數(shù)的誤差,實(shí)現(xiàn)了類型安全并且高精度的時間單位轉(zhuǎn)換。

3. 數(shù)值表示與存儲

duration 類內(nèi)部使用 Rep_ 類型存儲時間間隔的數(shù)值:

private:
    Rep_ rep_;

通過公開的 count() 方法獲取存儲的數(shù)值:

constexpr Rep_ count() const {
    return rep_;
}

4. 構(gòu)造函數(shù)設(shè)計(jì)

duration 提供了多種構(gòu)造方式以滿足不同需求:

/// 默認(rèn)構(gòu)造,數(shù)值為0
constexpr duration() : rep_() {}  
/// 從數(shù)值構(gòu)造
template<typename Rep2_>
explicit constexpr duration(const Rep2_ &r_) : rep_(r_) {}  
/// 從其他duration構(gòu)造
template<typename Rep2_, typename Period2_>
constexpr duration(const duration<Rep2_, Period2_> &d_)
    : rep_(duration_cast<duration>(d_).count()) {}  

運(yùn)算符重載與算術(shù)操作

duration 類實(shí)現(xiàn)了完整的算術(shù)運(yùn)算符重載,使得時間間隔的計(jì)算變得直觀自然。核心的思想都是將其轉(zhuǎn)換為相同單位后再進(jìn)行運(yùn)算。

1. 一元運(yùn)算符

/// 正號
constexpr duration operator+() const { return *this; }  
/// 負(fù)號
constexpr duration operator-() const { return duration(-count()); }  

2. 遞增遞減運(yùn)算符

/// 前置遞增
duration &operator++() { 
    ++rep_; 
    return *this; 
}  
/// 后置遞增
duration operator++(int) { 
    duration temp_(*this);
    ++*this; 
    return temp_; 
}  
/// 遞減運(yùn)算符類似,不重復(fù)貼出實(shí)現(xiàn)源碼

3. 復(fù)合賦值運(yùn)算符

實(shí)現(xiàn)復(fù)合運(yùn)算符進(jìn)行的方式都是類似的,這里給出+=的實(shí)現(xiàn)方式,其他運(yùn)算符類似。

duration &operator+=(const duration &d_) { 
    rep_ += d_.count(); 
    return *this; 
}

4. 二元運(yùn)算符實(shí)現(xiàn)

二元運(yùn)算符的實(shí)現(xiàn)采用了"統(tǒng)一單位后計(jì)算"的策略:

template<typename Rep1_, typename Period1_, typename Rep2_, typename Period2_>
constexpr auto operator+(const mychrono::duration<Rep1_, Period1_> &lhs,
                         const mychrono::duration<Rep2_, Period2_> &rhs) {
    /// 找出更高精度的時間單位
    using CommonPeriod = typename mychrono::higher_precision_duration<Rep1_, Period1_, Rep2_, Period2_>::type::period;
    /// 確定統(tǒng)一的數(shù)值類型
    using CommonRep = typename std::common_type<Rep1_, Rep2_>::type;
    using CommonDuration = mychrono::duration<CommonRep, CommonPeriod>;
    /// 轉(zhuǎn)換到統(tǒng)一類型后計(jì)算
    CommonRep lhs_val = duration_cast<CommonDuration>(lhs).count();
    CommonRep rhs_val = duration_cast<CommonDuration>(rhs).count();
    return CommonDuration(lhs_val + rhs_val);
}

關(guān)鍵步驟包括:

  1. 確定更高精度的時間單位(周期更小的單位)
  2. 確定統(tǒng)一的數(shù)值類型(使用 std::common_type
  3. 將兩個操作數(shù)轉(zhuǎn)換為統(tǒng)一類型
  4. 執(zhí)行算術(shù)運(yùn)算并返回結(jié)果

精度選擇與類型推導(dǎo)

1. 更高精度類型的選擇

higher_precision_duration 結(jié)構(gòu)體用于在兩個 duration 類型中選擇精度更高的類型:

template<typename Rep1_, typename Period1_, typename Rep2_, typename Period2_>
struct higher_precision_duration {
    using type = typename std::conditional<
            ratio_less<Period1_, Period2_>::value,
            duration<Rep1_, Period1_>,
            duration<Rep2_, Period2_>>::type;
};
  • 通過 ratio_less 比較兩個時間單位的周期
  • 選擇周期更?。ň雀撸┑?duration 類型作為結(jié)果

2. 數(shù)值類型的安全處理

在進(jìn)行算術(shù)運(yùn)算時,使用 std::common_type 確定安全的數(shù)值類型,定義與頭文件如下:

#include <type_traits>
template< class... T >
struct common_type;
template< class... T >
using common_type_t = typename common_type<T...>::type;  // C++14起的別名模板

實(shí)現(xiàn)的功能是:同時給出多個類型 T1、T2…,Tn,std::common_type會推導(dǎo)出一個公共類型,使得所有的Ti類都可以隱式轉(zhuǎn)換到公共類型,同時是可以同時滿足所有類型的最小公共類型。

所以,在復(fù)現(xiàn)過程中使用如下方式,找到公共類型:

using CommonRep = typename std::common_type<Rep1_, Rep2_>::type;

這種方式確保了不同數(shù)值類型(如 intlong long)之間的運(yùn)算不會發(fā)生精度丟失。

預(yù)定義的時間單位

為了方便使用,代碼中預(yù)定義了常見的時間單位特化:

using nano = ratio<1, 1000000000>;
using micro = ratio<1, 1000000>;
using milli = ratio<1, 1000>;
using nanoseconds = duration<int64_t, nano>;
using microseconds = duration<int64_t, micro>;
using milliseconds = duration<int64_t, milli>;
using seconds = duration<int64_t, ratio<1>>;
using minutes = duration<int64_t, ratio<60>>;
using hours = duration<int64_t, ratio<3600>>;
using days = duration<int64_t, ratio<86400>>;

這些定義使得我們可以用有意義的類型名表示不同精度的時間間隔,例如:

milliseconds ms(1000);  /// 1000毫秒
seconds s(1);           /// 1秒
hours h(24);            /// 24小時

使用示例

下面給出關(guān)于 duration 類的使用方法:

1. 基本時間間隔創(chuàng)建

/// 創(chuàng)建不同單位的時間間隔
milliseconds ms(500);        /// 500毫秒
seconds s(1);                /// 1秒
minutes m(10);               /// 10分鐘
/// 從其他duration構(gòu)造
seconds s2(ms);              /// 500毫秒轉(zhuǎn)換為0秒(發(fā)生截?cái)啵?
milliseconds ms2(s);         /// 1秒轉(zhuǎn)換為1000毫秒

2. 時間間隔計(jì)算

seconds s1(5);
seconds s2(3);
/// 加法運(yùn)算
seconds s_sum = s1 + s2;     /// 8秒
/// 減法運(yùn)算
seconds s_diff = s1 - s2;    /// 2秒
/// 復(fù)合賦值
s1 += s2;                    /// s1現(xiàn)在為8秒
/// 不同單位的運(yùn)算
milliseconds ms(1500);
seconds s_total = s1 + ms;   /// 自動轉(zhuǎn)換為秒后相加,結(jié)果為9.5秒(假設(shè)使用浮點(diǎn)類型)

3. 單位轉(zhuǎn)換

seconds s(1);
/// 轉(zhuǎn)換為毫秒
milliseconds ms = duration_cast<milliseconds>(s);  /// 1000毫秒
/// 轉(zhuǎn)換為納秒
nanoseconds ns = duration_cast<nanoseconds>(s);    /// 1000000000納秒
/// 精度損失示例
milliseconds ms(500);
seconds s = duration_cast<seconds>(ms);            /// 0秒

設(shè)計(jì)亮點(diǎn)與技術(shù)總結(jié)

1. 編譯期計(jì)算優(yōu)化

通過使用 ratio 模板中的(ratio_divideratio_less 等方法),許多計(jì)算可以在編譯期完成,在編譯期計(jì)算可以:

  • 提高運(yùn)行時效率,避免重復(fù)計(jì)算
  • 提前發(fā)現(xiàn)潛在的單位轉(zhuǎn)換錯誤
  • 支持編譯期常量表達(dá)式(constexpr

2. 類型安全設(shè)計(jì)

  • 不同單位的 duration 是不同的類型,避免了隱式轉(zhuǎn)換錯誤
  • 通過 explicit 構(gòu)造函數(shù)防止意外類型轉(zhuǎn)換
  • 精確的模板類型推導(dǎo)確保了運(yùn)算的安全性

3. 擴(kuò)展性設(shè)計(jì)

  • 基于模板的設(shè)計(jì)使得可以輕松支持自定義時間單位
  • 統(tǒng)一的接口設(shè)計(jì)使得新的時間單位可以無縫融入現(xiàn)有框架
  • 通過 duration_cast 實(shí)現(xiàn)任意單位之間的轉(zhuǎn)換

與標(biāo)準(zhǔn)庫 <chrono> 的對比

本文復(fù)現(xiàn)的 duration 類實(shí)現(xiàn)了標(biāo)準(zhǔn)庫 <chrono>duration 類的核心功能,但也存在一些差異:

  1. 命名空間:復(fù)現(xiàn)版本使用 mychrono 命名空間,這里是我基于std::chrono實(shí)現(xiàn)的我自己的mychrono
  2. 完整度:標(biāo)準(zhǔn)庫實(shí)現(xiàn)更為完整,包含更多的特化和輔助功能,我以學(xué)習(xí)和理解原理為主,故只完成部分內(nèi)容
  3. 錯誤處理:標(biāo)準(zhǔn)庫包含更完善的錯誤處理機(jī)制
  4. 浮點(diǎn)支持:復(fù)現(xiàn)版本主要使用整數(shù)類型,標(biāo)準(zhǔn)庫同時支持浮點(diǎn)類型

總結(jié)

duration 類是 C++ 時間處理的基礎(chǔ)組件,其設(shè)計(jì)思想體現(xiàn)了現(xiàn)代 C++ 模板編程的強(qiáng)大實(shí)力。通過將時間單位和數(shù)值表示分離,duration 實(shí)現(xiàn)了靈活而類型安全的時間間隔表示和計(jì)算。完成對duration的理解學(xué)習(xí)之后,對模板元編程方法理解更深刻。

最后,本文僅僅是我在學(xué)習(xí)復(fù)習(xí)相關(guān)知識點(diǎn)的時候進(jìn)行的自我總結(jié)和整理,存在很多不好的地方,如果錯誤請指出,接收一切批評并加以改正,認(rèn)真學(xué)技術(shù),加油。如有侵權(quán),請聯(lián)系我刪除~

到此這篇關(guān)于C++ 時間庫實(shí)現(xiàn):duration 類的原理與復(fù)現(xiàn)解析的文章就介紹到這了,更多相關(guān)C++ 時間庫duration 類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Protobuf C++ serialize到char*的實(shí)現(xiàn)方法分析

    基于Protobuf C++ serialize到char*的實(shí)現(xiàn)方法分析

    本篇文章是對Protobuf C++ serialize到char*的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • 一文讀懂C++中指針和內(nèi)存分配

    一文讀懂C++中指針和內(nèi)存分配

    我們知道聲明的所有變量在內(nèi)存中都有一個特定的地址。聲明一個指針變量來指向內(nèi)存中的這些地址,這篇文章主要介紹了C++中指針和內(nèi)存分配,需要的朋友參考下吧
    2021-06-06
  • C++模擬鍵盤按鍵的實(shí)例

    C++模擬鍵盤按鍵的實(shí)例

    今天小編就為大家分享一篇C++模擬鍵盤按鍵的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • C++執(zhí)行Linux Bash命令的方法

    C++執(zhí)行Linux Bash命令的方法

    今天小編就為大家分享一篇C++執(zhí)行Linux Bash命令的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • 一篇文章詳細(xì)解釋C++的友元(friend)

    一篇文章詳細(xì)解釋C++的友元(friend)

    這篇文章主要為大家詳細(xì)介紹了C++的友元(friend),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++ AVLTree高度平衡的二叉搜索樹深入分析

    C++ AVLTree高度平衡的二叉搜索樹深入分析

    這篇文章主要介紹了C++ AVLTree高度平衡的二叉搜索樹,二叉搜索樹雖可以縮短查找的效率,但如果數(shù)據(jù)有序或接近有序二叉搜索樹將退化為單支樹,查找元素相當(dāng)于在順序表中搜索元素,效率低下
    2023-03-03
  • C++使用HTTP庫和框架輕松發(fā)送HTTP請求

    C++使用HTTP庫和框架輕松發(fā)送HTTP請求

    使用C++編程發(fā)送HTTP請求通常需要使用第三方的HTTP庫或框架,本文主要介紹了C++使用HTTP庫和框架輕松發(fā)送HTTP請求,感興趣的可以了解一下
    2023-12-12
  • VSCode (Visual Studio Code) V1.43.0下載并設(shè)置成中文語言的方法

    VSCode (Visual Studio Code) V1.43.0下載并設(shè)置成中文語言的方法

    Visual Studio Code是一款免費(fèi)開源的現(xiàn)代化輕量級代碼編輯器,支持語法高亮、智能代碼補(bǔ)全、自定義熱鍵、括號匹配、代碼片段、代碼對比 Diff、GIT 等特性,這篇文章主要介紹了VSCode (Visual Studio Code) V1.43.0下載并設(shè)置成中文語言,需要的朋友可以參考下
    2020-03-03
  • set_new_handler(0)有什么用

    set_new_handler(0)有什么用

    本文主要介紹了set_new_handler(0)有什么用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • C++算法學(xué)習(xí)之回溯法的應(yīng)用

    C++算法學(xué)習(xí)之回溯法的應(yīng)用

    這篇文章介紹了C++算法中回溯法的一些應(yīng)用,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05

最新評論

华池县| 彰化县| 南陵县| 汕尾市| 资溪县| 昆明市| 冀州市| 宿松县| 芷江| 那曲县| 新安县| 遵义县| 纳雍县| 芮城县| 东莞市| 瓦房店市| 沛县| 沛县| 莲花县| 芦山县| 南开区| 嵊泗县| 吴川市| 罗平县| 富裕县| 百色市| 上思县| 罗田县| 石河子市| 宜宾市| 水城县| 武清区| 五常市| 逊克县| 布尔津县| 婺源县| 黄浦区| 红桥区| 洛南县| 师宗县| 浙江省|