中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

STL迭代器萃取-創(chuàng)新互聯(lián)

導(dǎo)言 什么是迭代器

迭代器是一種抽象的設(shè)計概念,《Design Patterns》一書中對于 iterator 模式的定義如下:提供一種方法,使之能夠依序巡訪某個聚合物(容器)所含的各個元素,而又無需暴露該聚合物的內(nèi)部表述方式。

創(chuàng)新互聯(lián)建站是一家專業(yè)提供項城企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站制作、H5場景定制、小程序制作等業(yè)務(wù)。10年已為項城眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進行中。為什么需要迭代器萃取

有時在我們使用迭代器的時候,很可能會用到其相應(yīng)型別(associated type)。什么是相應(yīng)型別,迭代器所指之物的型別、所屬的類型(隨機迭代器、單向雙向、只讀只寫)便是。

如果我們想要以迭代器所指之物型別為類型聲明一個變量,該怎么辦呢?

一種解決方法是:利用 function template 的參數(shù)推倒(argument deducation)機制。

例如:

templatevoid func(I iter, T t) {T tmp;	// 成功聲明了迭代器所指之物類型的變量
}

templatevoid func(I iter) {func_impl(iter, *iter);
}

int main() {int num = 0;
    func(&num);
}

但迭代器的型別不只是迭代器所指對象的型別,而且上述解法并不能用于所有情況,因此需要更加全面的解法。

比如上述解法就無法解決 value type 用于函數(shù)返回值的情況,畢竟推導(dǎo)的只是參數(shù),無法推導(dǎo)返回值型別。

聲明內(nèi)嵌類型似乎是個很好的方法,像這樣:

templatestruct MyIter {typedef T value_type;
    T* ptr;
    
    MyIter(T* p) {ptr = p;
    }
    T& operator*() {return *ptr; 
    }
};

templatetypename I::valie_type func (I ite) {// typename I::valie_type 為返回值類型
	return *ite;
}

MyIterite(new int(1231));
cout<< func(ite)<< endl;

此處 typename 的作用是告訴編譯器這是一個類型,因為 I 是一個模板參數(shù),在它被具現(xiàn)化之前編譯器對它一無所知,也就是說編譯器不知道 I::valie_type 是個類型或是成員函數(shù)等等。

更多關(guān)于 typename 的用法可以看這個鏈接:typename 的用法

還有一種情況是上述代碼無法解決的,那就是不是所有的迭代器都是 class type,原生指針就不是。如果不是 class type 就無法為它定義內(nèi)嵌型別,因此我們需要對原生指針作些特殊處理。

例如:

templatestruct iterator_traits {typedef typename I::value_type value_type;
};
templatestruct iterator_traits{typedef T value_type;
};
templatestruct iterator_traits{typedef T value_type;
};

此時,不管是 class type 類型的迭代器還是原生指針都可以處理了。

迭代器萃取,就是為我們榨取出迭代器的相應(yīng)型別。當然,要使萃取有效的運行,每個迭代器都要自行以內(nèi)嵌性別定義(nested typedef)的方式定義出相應(yīng)型別。

最常用的迭代器型別有五種:value type,difference type,pointer,reference,iterator catagoly。

迭代萃取機 traits 會很忠實地將它們榨取出來:

templatestruct iterator_traits {typedef typename I::iterator_category 	iterator_category;
    typedef typename I::value_type			value_ type;
    typedef typename I::difference_type		difference_type;
    typedef typename I::pointer				pointer;
    typedef typename I::reference			reference;
};

iterator_traits 必須針對傳入型別為 point 及 point-to-const 者,設(shè)計特化版本。

value type

value type 是指迭代器所指對象的型別。

做法如上文所述。

difference type

difference type 用來表示兩個迭代器之間的距離。對于連續(xù)空間的容器來說,頭尾之間的距離就是大容量,因此它也可以用來表示一個容器的大容量。

如果一個泛型算法提供記數(shù)功能,例如 STL 的count(),其返回值就必須使用迭代器的 difference type:

templatetypename iterator_traits::difference_type		// 返回值類型,實際是 I::difference type
    count(I first, I last, const T& value) {typename iterator_traits::difference_type ret = 0;
    for (; first != last; ++first) {if (*first == value) {ret++;
        }
    }
    return ret;
}

針對相應(yīng)型別 difference type,traits 的兩個特化版本,以 C++ 內(nèi)建的 ptrdiff_t 作為原生指針的 difference type。

templatestruct iterator_traits {typedef typename I::difference_type difference_type;
};
templatestruct iterator_traits{typedef ptrdiff_t difference_type;
};
templatestruct iterator_traits{typedef ptrdiff_t difference_type;
};
reference type

從迭代器所指之物的內(nèi)容是否允許改變的角度來說,迭代器分為兩種:不允許改變所指對象的內(nèi)容者,稱為 constant iterators;允許改變所指對象的內(nèi)容者,稱為 mutable iterators。當我們對允許改變內(nèi)容的迭代器進行解引用操作時,獲得的不應(yīng)是一個右值,應(yīng)該是一個左值,因為右值不允許賦值操作。

在 C++ 中,函數(shù)如果要傳回左值,都是以引用的方式進行。所以當 p 是個 mutable iterators 時,如果其 value type 是 T,那么 *p 的型別不應(yīng)該是 T,而應(yīng)是 T&。同樣的,如果 p 是一個 constant iterators,其 value type 是 T,那么 *p 的型別不應(yīng)該是 const T,而應(yīng)該是 const T&。實現(xiàn)將在下一部分給出。

point type

同樣的問題也出現(xiàn)在指針這里,能否改變所指地址的內(nèi)容,影響著取出的指針類型。

實現(xiàn)如下:

templatestruct iterator_traits {typedef typename I::pointer 	pointer;
    typedef typename I::reference	reference;
};
templatestruct iterstor_traits{typedef T* 	pointer;
    typedef T& 	reference;
};
templatestruct iterstor_traits{typedef const T*	pointer;
    typedef const T& 	reference;
};
iterator_category

根據(jù)移動特性與施行操作,迭代器被分為五類:

請?zhí)砑訄D片描述

前三種支持operator++,第四種再加上oprerator--,最后一種則涵蓋所有指針算術(shù)能力。

這些迭代器的分類與從屬關(guān)系,可以用下圖表示。直線與箭頭并非表示繼承關(guān)系,而是所謂概念與強化的關(guān)系。更類似于,隨機迭代器是一個雙向迭代器,雙向迭代器也是一個單向迭代器的概念。
請?zhí)砑訄D片描述

設(shè)計一個算法時,要盡可能針對圖中某種迭代器提供一個明確定義,并針對更加強化的某種迭代器提供另一種定義,這樣才能在不同情況下提供大效率。

以 distance() 為例

distance()函數(shù)用來計算兩個迭代器之間的距離。針對不同的迭代器類型,它可以用不同的計算方式,帶來不同的效率。

templateinline iterator_traits::difference_type
    __distance(InputIterator first, InputIterator last,
              input_iterator_tag) {iterator_traits::iteratordifference_type n = 0;
    // 逐一累計距離
    while (first != last) {++first;
        ++n;
    }
    return n;
}

templateinline iterator_traits::difference_type
    __distance(RandomAccessIterator first, RandomAccessIterator last,
               random_access_iterator_tag) {// 直接計算差距
    return last - first;
}

// InputIterator 命名規(guī)則:所能接受的最低階迭代器類型
templateinline iterator_traits::difference_type
    distance(InputIterator first, InputIterator last) {typedef typename iterator_traits::iterator_category category;
    return __distance(first, last, category());
}

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

本文名稱:STL迭代器萃取-創(chuàng)新互聯(lián)
文章URL:http://m.rwnh.cn/article30/cciepo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、網(wǎng)站導(dǎo)航靜態(tài)網(wǎng)站、網(wǎng)站策劃、網(wǎng)站維護網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

隆安县| 涿鹿县| 正蓝旗| 洛隆县| 毕节市| 和龙市| 静海县| 大宁县| 遂川县| 中山市| 辽中县| 镇康县| 精河县| 金山区| 惠水县| 扶余县| 桓台县| 秦安县| 禹州市| 平南县| 宁强县| 新乐市| 沭阳县| 拜城县| 建德市| 西青区| 抚顺市| 铜川市| 涿州市| 平江县| 宜川县| 伊春市| 麻江县| 赤城县| 罗平县| 辽中县| 木里| 龙山县| 嘉峪关市| 克什克腾旗| 额济纳旗|