標題<ratio>允許您使用模板元編程來處理和操作有理值。
但是 - 它是在 C 11 中引入的,當時我們已經有了constexpr. 為什么有一個完全constexpr'ifed 的有理數庫型別還不夠好,即基本上:
template<typename I>
struct rational {
I numerator;
I denominator;
};
并改用它?
使用 C 11 的 constexpr 功能是否有一些具體的好處std::ratio還不夠適合?如果是這樣,它在 C 20 中是否仍然相關(使用 constexpr 的擴展“范圍”)?
uj5u.com熱心網友回復:
使用 C 11 constexpr 功能不適合的 std::ratio 是否有一些具體的好處?
ratio您可以作為模板型別引數傳遞,這就是這樣std::chrono::duration做的。要使用基于值的比率來做到這一點,您需要 C 20 或更高版本。
在 C 20 和更新版本中,我看不到當前設計的任何好處。
uj5u.com熱心網友回復:
這里有幾個答案和評論,但我認為它們都沒有真正將std::ratio. 讓我們從 的定義開始std::ratio。它大致相當于:
template<int Num, int Den>
struct ratio {
static constexpr int num = Num;
static constexpr int den = Den;
};
但是,您可能可以將其用作替代方法,std::ratio如下所示:
template<typename I>
struct ratio {
I num;
I den;
};
使用一堆constexpr函式來執行該型別的算術運算。
請注意,這兩個定義之間存在細微但非常重要的區別。而在第二個定義中,比率 (num和den) 的實際值存盤在型別的實體中,而在第一個定義中,值實際上存盤在型別本身中。
如果你有一個類似的庫std::chrono,你想要一個型別,它可以將時間存盤為毫秒數(例如std::chrono::milliseconds)。如果您稍后想將此數字轉換為秒,您不想將轉換比率編碼到實體中,std::chrono::milliseconds而是編碼到型別本身。這就是為什么std::chrono使用第一種形式而不是第二種形式(或簡單的浮點值)的原因。
要將數字存盤到型別而不是實體中,您需要一個非型別模板引數。在 C 20 之前,您只能對非型別模板引數使用整數值。盡管如此,為了存盤標準庫的合理轉換因子,指定了std::ratio類模板。
在 C 20 中,潮流發生了一點變化,因為您現在可以使用浮點數作為非型別模板引數。例如,std::chrono::duration可以重寫為:
template<..., double conversion_factor, ...>
duration {
...
};
但是,此 C 20 功能與您在問題中提到的“constexpr 的擴展范圍”無關。編譯時間計算不同于將數值存盤在型別本身中,盡管您需要第一個來執行第二個。
類模板的使用std::ratio(專門)用于將值存盤到型別中。
uj5u.com熱心網友回復:
為什么在型別 I 上為有理數提供完全 constexpr'ifed 庫型別并改用它還不夠好?
重要的一點是,任何低于 1 的值都不能與僅使用 constexpr 的整數值一起保存。如果您需要浮點數,則會遇到準確性和舍入問題。
此外,如果您考慮在最大 int 型別為 16 位的小型嵌入式設備上,您可以毫無問題地存盤 32 位中的所有值,并且數學可以根據需要精確,而不會在浮點表示的最低有效位下運行該實施。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/455161.html
上一篇:CRTP基私有建構式和派生的友元類使用C 17和統一初始化導致編譯錯誤
下一篇:減少記憶體對齊
