首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

泛型編程挑戰:重寫 Min/Max 突破宏與模板局限

     編輯:關於C++

Scott Meyers 的挑戰 (1995)

「實現 max 的最佳方法是什麼?我不知道。」—— 宏有副作用雙重求值,簡單模板無法處理 const/非 const、混合類型、繼承層次切片等問題。

宏版本缺陷


#define min(a,b) ((a)<(b)?(a):(b))
int c = min(a++, b);  // a++ 執行兩次!c=4 而非預期 3

簡單模板缺陷


const T& min(const T& a, const T& b) { return a

Loki 庫技術棧

  • Typelist:編譯期類型列表 `TYPELIST_3(float, double, long double)`
  • Select:編譯期條件選擇 `Select<cond, T, U>::Result`
  • TypeTraits:類型屬性推導 `TypeTraits<T>::NonConstType`
  • Conversion:隱式轉換檢測 `Conversion<T, U>::exists`

MinMaxTraits:編譯期推導返回類型


namespace Private {
    typedef TYPELIST_14(
        const bool, const char, const signed char, const unsigned char,
        const wchar_t, const short, const unsigned short,
        const int, const unsigned int,
        const long, const unsigned long,
        const float, const double, const long double
    ) ArithTypes;  // 算術類型優先級順序:低→高
}

template <class L, class R>
struct MinMaxTraits {
    // 算法:
    // 1. 假設結果為 R
    // 2. 若 R 隱式轉換到 L → 結果為 L
    // 3. 若 R 在 ArithTypes 中位於 L 之後 → 結果為 R (數學擴展)
    // 4. 若 L& 可隱式轉換到 R& (無臨時量) → 結果為 R& (防切片)
    // 5. 若 R& 可隱式轉換到 L& → 結果為 L&
    typedef /* 編譯期計算結果 */ Result;
};

四個重載覆蓋 const/非 const 組合


template <class L, class R>
typename MinMaxTraits<L, R>::Result Min(L& a, R& b) {
    if (a < b) return a; else return b;  // 避免 a

關鍵創新點

  1. 可配置的類型推導算法:`MinMaxTraits` 封裝邏輯,用戶可擴展 `ArithTypes` 或修改規則
  2. 防切片返回**:`if (a
  3. 支持繼承層次**:`Shape&` / `Rectangle&` 正確返回 `Shape&`,不切片
  4. 支持混合算術類型**:`min(int, double) → double&`

滿足 Scott 的四項要求

要求本實現
語義類型檢查模板參數推導 + 轉換檢測
支持 const/非 const四個重載全覆蓋
支持不同類型智能推導通用類型
無需顯式實例化自動推導

遺憾與現代視角

  • 代碼依賴 Loki 庫,編譯器兼容性有限(文中提及部分編譯器無法通過)
  • C++11 起 `std::common_type`、`decltype(auto)`、概念 (C++20) 可更簡潔實現
  • 現代寫法:

template <class L, class R>
auto min(L&& a, R&& b) -> decltype(a < b ? std::forward<L>(a) : std::forward<R>(b)) {
    return a < b ? std::forward<L>(a) : std::forward<R>(b);
}

但文章展示的「類型推導算法可編程」思想仍具啟發意義。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved