2016-11-15 90 views
3

我正在根據計數排序製作自己的sort()算法。它對範圍有限的正數進行排序。到目前爲止,它在std :: string和std :: vector上工作。在模板函數中需要什麼類型的迭代器?

的原型如下:

template<class ForwardIterator, int maxNumbers> 
void sortIntegers(ForwardIterator start, ForwardIterator end) 

我的算法使用*iter =++itercopy = iter。從http://www.cplusplus.com/reference/iterator/我確定我需要一個ForwardIterator或更好的。

這是確定我的算法需要的最常用類型的迭代器的正確方法嗎?我不確定我應該試圖成爲通用的。我只是猜我應該。這樣我可以支持最多的容器。然後,當我看着STL sort()時,我發現它使用了隨機訪問迭代器(http://www.cplusplus.com/reference/algorithm/sort/)。對我而言,這意味着它受限於它支持的容器。例如,它會在名單上工作嗎?

我認爲STL做得很對。那麼,爲什麼我的錯誤只需要在我的函數中使用ForwardIterator?也許當我測試更多容器類型時,我會意識到我需要更嚴格?另外作爲獎勵,我知道只將類類型命名爲ForwardIterator只是文檔要求。 STL是否做了更多的工作以確保傳遞給sort()的是一個隨機訪問迭代器?所以如果我傳入一個列表迭代器來排序(),我假設我得到錯誤。這些錯誤如何產生?

+2

我建議使用[en.cppreference.com](http://en.cppreference.com/w/cpp/iterator),而不是那些不可靠的cplusplus.com的東西。 –

+0

'std :: sort'需要隨機訪問,因爲'qsort'需要隨機訪問。 – NathanOliver

+0

'std :: sort'不適用於'std :: list',但是'std :: list'提供它自己的版本,作爲成員函數'std :: list :: sort'。 –

回答

2

這是確定我的算法需要的最一般類型的迭代器的正確方法嗎?

嗯,是的。查看這些概念並確定您的算法需要哪種迭代器概念纔是正確的選擇。

對我來說,這意味着它受限於它支持的容器。例如,它會在名單上工作嗎?

不,這不會對std::list工作,因爲std::list只有對BidirectionalIterator概念,RandomAccessIterator的派生自支持。是的,因爲它在某些容器上是有限的。

那麼,爲什麼我錯了,只需要我的函數中的ForwardIterator?

這沒有錯,但你是有限的,即你不能例如使用--it,但如果這是好的,那麼就沒有什麼不妥的地方。 C++只是想給我的實現儘可能多的自由,我認爲。

STL是否做了更多的工作以確保傳遞給sort()的是一個隨機訪問迭代器?

不,沒有保護。唯一的問題是,如果你不是使用RandomAccessIterator調用它,你將會得到一個錯誤(或多個錯誤),因爲你的迭代器不支持std::sort要求的操作(如[],--,...)。

Concepts有一個TS,它可以做到這一點,對模板參數執行編譯時需求,並在使用錯誤類型時產生有用的錯誤消息。但是,這可能是C++ 20的問題。

你也可以做一個特徵檢查來檢查迭代器的標籤,就像@JustinTime所建議的那樣,但這是標準所不需要的,所以沒有或很少有實現實際上這樣做(我什麼都不知道,所以我可以對此不確定)。

+0

定義[iterator標記的特徵檢查](http://ideone.com/Fc9ncr)很容易。 'check_iter()'也可以被重寫以獲取一個標籤來檢查模板參數,並確定具有預處理器魔術的'UseIteratorTraits'。 –

+0

@JustinTime Jup,雖然我不完全稱它爲「easy」:)謝謝 – Rakete1111

+0

不客氣。將其更改爲更通用,並提供瞭如何使用它的示例。函數本身中的'static_assert'是多餘的,但允許它在另一個'static_assert'或'bool'模板參數中使用。 –

0

嗯,你不是要求參數要ForwardIterator這兒。

你看,template<class ForwardIterator, int maxNumbers>意味着該模板接受兩個參數:其中一個是一個類,另一個是一個整數。請注意,沒有要求或限制是強加於那種類。 C++ 並不是關心一個參數的名稱那麼多,它更關心類型。

相關問題