模板超程式設計之 std::iterator_traits<> 型別計算
阿新 • • 發佈:2021-01-08
我們來解析一段程式碼:
1 template<class..._Ty> 2 using void_t = void; 3 4 template <class, class = void> 5 struct _Iterator_traits_base {}; // empty for non-iterators 6 7 template <class _Iter> 8 struct _Iterator_traits_base<_Iter, 9 void_t<typename _Iter::iterator_category, typename _Iter::value_type, typename _Iter::difference_type,10 typename _Iter::pointer, typename _Iter::reference>> { 11 // defined if _Iter::* types exist 12 using iterator_category = typename _Iter::iterator_category; 13 using value_type = typename _Iter::value_type; 14 using difference_type = typename _Iter::difference_type; 15 usingpointer = typename _Iter::pointer; 16 using reference = typename _Iter::reference; 17 };
這段程式碼是我們從C++標準庫中擷取到程式碼,首先我們看第一段,(1-2)定義了一個範圍。
(4-5)定義了一個特化版本,用來停止迭代
(7-16)這是我們要講的重點,首先聲明瞭一個型別_Iter,然後下面緊跟的是我們演算法實現部分,
方法名後面的是型別的宣告,就是說,我們這個方法有,Iter,和型別集合型別。
然後我們看,邏輯體,using 聲明瞭傳入型別的型別,這是什麼意思呢,就是我們這個模板的成員屬性,也是我們傳入型別的屬性,
比如我們傳入一個容器的迭代器型別的時候我們訪問的就是迭代器型別的型別:
1 std::iterator_traits<std::vector<int>::iterator>::value_type m = 100; 2 //m在這裡就是一個int型別
有同學就說了,我直接訪問型別的迭代器型別不就行,為什麼要多此一舉呢?
這裡體現的泛型,什麼是泛型呢,就是廣泛使用的型別,我們可以使用這一個模板訪問所有的此模板內的物件的屬性型別,這就有效減少了程式碼的重複性
並且呢,此模板沒有包含執行時的程式碼,所以呢,在編譯期,程式碼就會被執行轉換。這也是超程式設計的最重要的思想
上面我們寫的std::iterator_traits 是繼承自_Iterator_traits_base ,做了一個封裝,