亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

duration 類的基本概念

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

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

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

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

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

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

duration 類的模板定義如下:

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

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

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

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

 /// 用于將一個(gè)時(shí)間段從一個(gè)周期單位轉(zhuǎn)換到另一個(gè)周期單位
    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ì)算兩個(gè)時(shí)間單位的轉(zhuǎn)換因子(時(shí)間轉(zhuǎn)換因子用于在不同時(shí)間單位或者系統(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)行時(shí)的效率,同時(shí)又避免了浮點(diǎn)數(shù)的誤差,實(shí)現(xiàn)了類型安全并且高精度的時(shí)間單位轉(zhuǎn)換。

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

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

private:
    Rep_ rep_;

通過公開的 count() 方法獲取存儲(chǔ)的數(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)算符重載,使得時(shí)間間隔的計(jì)算變得直觀自然。核心的思想都是將其轉(zhuǎn)換為相同單位后再進(jìn)行運(yùn)算。

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

/// 正號(hào)
constexpr duration operator+() const { return *this; }  
/// 負(fù)號(hào)
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) {
    /// 找出更高精度的時(shí)間單位
    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. 確定更高精度的時(shí)間單位(周期更小的單位)
  2. 確定統(tǒng)一的數(shù)值類型(使用 std::common_type
  3. 將兩個(gè)操作數(shù)轉(zhuǎn)換為統(tǒng)一類型
  4. 執(zhí)行算術(shù)運(yùn)算并返回結(jié)果

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

1. 更高精度類型的選擇

higher_precision_duration 結(jié)構(gòu)體用于在兩個(gè) 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 比較兩個(gè)時(shí)間單位的周期
  • 選擇周期更?。ň雀撸┑?duration 類型作為結(jié)果

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

在進(jìn)行算術(shù)運(yùn)算時(shí),使用 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)的功能是:同時(shí)給出多個(gè)類型 T1、T2…,Tn,std::common_type會(huì)推導(dǎo)出一個(gè)公共類型,使得所有的Ti類都可以隱式轉(zhuǎn)換到公共類型,同時(shí)是可以同時(shí)滿足所有類型的最小公共類型。

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

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

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

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

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

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>>;

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

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

使用示例

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

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

/// 創(chuàng)建不同單位的時(shí)間間隔
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. 時(shí)間間隔計(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;   /// 自動(dòng)轉(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_divide、ratio_less 等方法),許多計(jì)算可以在編譯期完成,在編譯期計(jì)算可以:

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

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

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

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

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

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

本文復(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. 錯(cuò)誤處理:標(biāo)準(zhǔn)庫包含更完善的錯(cuò)誤處理機(jī)制
  4. 浮點(diǎn)支持:復(fù)現(xiàn)版本主要使用整數(shù)類型,標(biāo)準(zhǔn)庫同時(shí)支持浮點(diǎn)類型

總結(jié)

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

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

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

相關(guān)文章

最新評(píng)論