日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用traits技术表现迭代器类型 iterator_category

發(fā)布時(shí)間:2023/12/10 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用traits技术表现迭代器类型 iterator_category 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.STL的迭代器類型標(biāo)識,和容器中的迭代器類型。

2.使用trait技術(shù)實(shí)現(xiàn)stl的advance功能。

3.迭代器trait中的其他類型定義。?

?

1.STL的迭代器類型標(biāo)識,和容器中的迭代器類型。

?熟悉的迭代器類型,輸入、輸出、前向、雙向、隨機(jī)。

c++標(biāo)準(zhǔn)程序庫分別提供專屬的卷標(biāo)結(jié)構(gòu)(tag struct),一個(gè)空的結(jié)構(gòu)體來標(biāo)志具體是哪種類型迭代器。如下:

// ITERATOR STUFF (from <iterator>)// ITERATOR TAGS (from <iterator>) struct input_iterator_tag{ // identifying tag for input iterators };struct output_iterator_tag{ // identifying tag for output iterators };struct forward_iterator_tag: input_iterator_tag, output_iterator_tag{ // identifying tag for forward iterators 這些繼承關(guān)系有有效的IS-A };struct bidirectional_iterator_tag: forward_iterator_tag{ // identifying tag for bidirectional iterators };struct random_access_iterator_tag: bidirectional_iterator_tag{ // identifying tag for random-access iterators};

而在每個(gè)容器中,就使用上述的tag struct標(biāo)識自自身迭代器的類型,大概的思路是下面的樣子,但真正源碼實(shí)現(xiàn)復(fù)雜多。

// vector 容器 隨機(jī)迭代器。list 容器 雙向迭代器。
template<...> class vector{ public: class iterator{ public: typedef random_access_iterator_tag iterator_category;
     // 類型定義: vector<T>::iterator::iterator_category 就是 random_access_iterator_tag
     // 即類型里面還有一個(gè)類型, 而這個(gè)類型僅僅是用來標(biāo)識 這個(gè)類是屬于哪個(gè)類型的。 }; };template
<...> class list{ public: class iterator{ public: typedef bidirectional_iterator_tag iterator_category; }; };

?

2.使用trait技術(shù)實(shí)現(xiàn)stl的advance功能。

STL標(biāo)準(zhǔn)模版庫={容器templates,迭代器templates(關(guān)聯(lián)容器 和 算法),算法templates,工具性template如advance}。這里選擇迭代器模版和Advance的實(shí)現(xiàn)來講解trait技術(shù)。

?

先看看advance的用法:

// advance 函數(shù)簽名
std::advance template
<class Iterator, class Distance>void advance (Iterator& it, Distance n);
// advance example #include <iostream> // std::cout #include <iterator> // std::advance #include <list> // std::listint main () {std::list<int> mylist;for (int i=0; i<10; i++) mylist.push_back (i*10);std::list<int>::iterator it = mylist.begin();std::advance (it,5); std::cout << "The sixth element in mylist is: " << *it << '\n';return 0; }

advance內(nèi)部操作時(shí)候,需要知道advance的迭代器類型,看有哪些可用操作,比如隨機(jī)訪問器可以直接+= -=操作,前向僅支持++,輸入輸出均不支持,例子中的list屬于雙向,支持++,--。

所以在advance內(nèi)部需要在取得某種類型信息,即迭代器的類型,進(jìn)行不同的實(shí)現(xiàn)。

?

如何取得類型信息呢,在1中其實(shí)我們已經(jīng)定義了迭代器的類型,可以通過 ”容器類型::iterator::iterator_category“來獲取類型信息。

但如果要支持內(nèi)置類型,比如指針是一種隨機(jī)迭代器類型,那么類型信息就不能放在類型內(nèi)了,意味著類型內(nèi)的嵌套類的方式不能工作,所以類型的信息必須位于類型自身之外。

?

trait標(biāo)準(zhǔn)技術(shù)是把它放進(jìn)一個(gè)template,并進(jìn)行一個(gè)偏特化版本,來實(shí)現(xiàn)迭代器所屬類型trait。trait特性的意思 就有有關(guān)迭代器的相關(guān)特性。

// 即再封裝一層,如果是用戶自定義的,就直接獲取內(nèi)部定義的迭代器類型 // 如果是內(nèi)置類型,就直接給設(shè)定成他所屬的迭代器類型,用模版偏特化 // iterator_traits template<typename IterT> struct iterator_traits{ typedef typename IterT::iterator_category iterator_category; // 注意: 這里typename關(guān)鍵字 指示編譯器解析 IterT::iterator_category 為一個(gè)類型 ... };template<typename IterT> //template 偏特化,針對內(nèi)置指針 struct iterator_traits<IterT*>{ typedef random_access_iterator_tag iterator_category; };

template<typename IterT> struct iterator_traits<const IterT*>{ typedef random_access_iterator_tag iterator_category; }; ?

?

在advance的用法中,就可以使用?iterator_traits 類來判斷是什么類型

// advance運(yùn)行時(shí)確定使用哪種迭代器類型版本
template<typename IterT, typename DistT> void advance(IterT& iter, DistT d) { if (typeid(typename std::iterator_traits<IterT>::iterator_category) == typeid(std::random_access_iterator_tag)) { iter += d;} else if(前向迭代器類型){ if (d < 0){throw std::out_of_range("Negative distance");} while (d--) ++iter; }else if(等等其他類型)... }

?

使用重載函數(shù)的機(jī)制,在編譯器就確定調(diào)用哪個(gè)迭代器類型的advance,以提高運(yùn)行時(shí)效率。

// advance編譯器確定使用哪種迭代器類型版本 template<typename IterT, typename DistT> void advance(IterT& iter, DistT d) { doAdvance(iter, d, typename std::iterator_traits<IterT>::iterator_category()); } // 比如 雙向迭代器的函數(shù) 。重載doAdvance,實(shí)現(xiàn)不同的迭代器類型的具體操作。 // 可以看到迭代器類型僅僅是個(gè)重載的作用,使得重載機(jī)制得以運(yùn)行,都不需要變量名。 void doAdvance(IterT& iter, DistT d, std::bidirectional_iterator_tag) { if (d >= 0) {while (d--) ++iter;} else {while(d++) --iter;} }

?

3.迭代器trait中的其他類型定義

?

?

template<class IterT> struct iterator_traits{typedef typename IterT::iterator_category iterator_category;  // 迭代器的類型所屬typedef typename IterT::value_type value_type;          // 迭代器所指對象的類型typedef typename IterT::difference_type difference_type;     // 迭代器之間的距離 typedef typename IterT::pointer pointer;              // 迭代器所指內(nèi)容的地址typedef typename IterT::reference reference;            // 迭代器所指之內(nèi)容 };template<typename IterT> //template 偏特化,針對內(nèi)置指針 struct iterator_traits<IterT*>{ typedef random_access_iterator_tag iterator_category; typedef IterT value_type; typedef ptrdiff_t difference_type ;
typedef IterT
* pointer ; typedef IterT& reference ; };

?

?

另外,STL提供了一個(gè) iterator類,如果每個(gè)新設(shè)計(jì)的迭代器都繼承他,可保證符合STL所需的規(guī)范。

// TEMPLATE CLASS iterator template<class _Category,class _Ty,class _Diff = ptrdiff_t,class _Pointer = _Ty *,class _Reference = _Ty&>struct iterator{ // base type for iterator classes typedef _Category iterator_category;typedef _Ty value_type;typedef _Diff difference_type;typedef _Pointer pointer;typedef _Reference reference;};

?

?

?

整理自 effective C++ 條款 47:使用traits classes表現(xiàn)類型信息

轉(zhuǎn)載于:https://www.cnblogs.com/fulina/p/7058288.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的使用traits技术表现迭代器类型 iterator_category的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。