Traits 是一種編程慣例,利用模板與特化在**編譯期**提供型別相關資訊(如迭代器類別、大小、是否為 POD 等),支援泛型程式設計中的條件編譯邏輯。
STL advance(iter, n) 需根據迭代器類別選擇最佳實作:
iter += n (O(1))++/-- (O(n))但迭代器型別千變萬化,如何統一查詢其類別?
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
繼承關係體現能力遞增,方便 is_base_of 檢查。
templateclass deque { public: class iterator { public: typedef random_access_iterator_tag iterator_category; // 標記類別 // ... }; };
// 主模板:適用於有 iterator_category 的使用者型別 templatestruct iterator_traits { typedef typename Iter::iterator_category iterator_category; typedef typename Iter::value_type value_type; typedef typename Iter::difference_type difference_type; typedef typename Iter::pointer pointer; typedef typename Iter::reference reference; }; // 偏特化:原生指標 T* template struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; }; // 偏特化:const T* template struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef const T* pointer; typedef const T& reference; };
// 主函數:提取 tag 並分派 templatevoid advance(Iter& iter, Dist n) { typename iterator_traits ::iterator_category cat; __advance(iter, n, cat); // 呼叫多載版本 } // 隨機存取版本 template void __advance(Iter& iter, Dist n, random_access_iterator_tag) { iter += n; } // 雙向版本 template void __advance(Iter& iter, Dist n, bidirectional_iterator_tag) { if (n >= 0) while (n--) ++iter; else while (n++) --iter; } // 輸入迭代器版本(不支援負向) template void __advance(Iter& iter, Dist n, input_iterator_tag) { if (n < 0) throw out_of_range("Negative distance"); while (n--) ++iter; }
編譯器根據 cat 型別自動選擇正確多載,**零運行期開銷**。
iterator_category)。iterator_category)。iterator_traits)。char_traits:字元操作特性。numeric_limits:數值型別範圍與屬性。type_traits (C++11):is_integral, is_class, remove_reference 等。