「實現 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
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;
};
template <class L, class R>
typename MinMaxTraits<L, R>::Result Min(L& a, R& b) {
if (a < b) return a; else return b; // 避免 a
| 要求 | 本實現 |
|---|---|
| 語義類型檢查 | 模板參數推導 + 轉換檢測 |
| 支持 const/非 const | 四個重載全覆蓋 |
| 支持不同類型 | 智能推導通用類型 |
| 無需顯式實例化 | 自動推導 |
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);
}
但文章展示的「類型推導算法可編程」思想仍具啟發意義。