2013-12-08 44 views
0

我經常發現自己使用依賴於開始迭代器和結束迭代器的std算法。爲什麼標準沒有包含以容器作爲參數的重載(而不是迭代器)。在標準中不包括這樣的東西是否有技術上的原因?STL中基於容器的重載

template <typename ContainerT, typename ValueT> 
typename ContainerT::iterator find(ContainerT& container, const ValueT& value) 
{ 
    return std::find(begin(container), end(container), value); 
} 

這在搜索整個向量時非常方便。我意識到如果你不想迭代整個容器,那麼仍然需要顯式的迭代器版本。

std::vector<std::string> v; 
v.push_back("foo"); 
v.push_back("bar"); 

std::find(v.begin(), v.end(), "bar"); 

find(v, "bar"); // much nicer! :) 
+1

你仍然需要訪問容器的'end()'函數來理解結果。總而言之,從中獲得的東西很少。圖書館已經有一套完善的工具,歡迎您自行構建您認爲對您的項目有用的簡短工具。 –

+0

希望有一天這將成爲可能,同時我將繼續使用我自己的「遠程」版本... –

回答

0

它不會在數組。例如:

int myArray* = new int[2354]; 

begin(myArray)end(myArray)沒有多大的意義。但std::find(myArray, myArray + 2354, value)會工作。

但標準確實允許它在當前接口上正確工作。

此外,你不總是希望我們的整個容器上的算法。

它僅適用於2個迭代器之間的間隔,因此您可以在容器中間的某些東西的形式上使用find()

+1

它將完美適用於數組,而不是針對指針。除此之外,選舉委員會特別表示,他不希望額外的重載取代而擴大現有的職能。當然,迭代器版本仍然是需要的(我並不是說需要額外的重載或任何有用的,只是答案沒有真正解決問題)。 –

0

我很驚訝沒有人提到過Boost Range library呢。它提供了你正在尋找的功能,並且有proposals添加類似於STL的東西。甚至可能有一個致力於範圍的ISO C++工作組,但我無法記住我的頭頂。

此外,這是我不同意Kerrek SB的罕見情況之一。將迭代器的抽象級別提高到範圍有很多實用工具,特別是在執行算法之前使用適配器修改範圍。 Boost範圍庫解釋了爲什麼這是一個重要的想法。作爲一個簡短的例子,考慮一系列你想訪問指示對象的指針。要做到這一點與迭代器,你需要做類似如下:

std::vector<int *> v; // populate with something. 

auto begin = boost::make_indirect_iterator(v.begin()); 
auto end = boost::make_indirect_iterator(v.end ()); 

std::for_each(begin, end, do_something); 

使用範圍的算法和適配器,我們可以在此更加簡潔表達,而且我認爲,明確提出:

boost::range::for_each(v | boost::adaptors::indirected, do_something); 

唯一目前Boost實現似乎缺乏的東西是像轉換和過濾這樣的範圍適配器在lambda功能方面還不夠好。不是對圖書館的投標,這從根本上改變了我的編碼方式。