![]() |
Boost.Range |
以一個抽像概念封裝一對迭代器是非常有用的。標準庫在某些環境下使用 std::pair,
但是這個類用起來有點麻煩,因為我們必須要指定兩個模板參數,而對於所有區間算法來說,我們必須強制讓兩個模板參數相同。此外,std::pair<iterator,iterator>
很難起一個易懂的類名。因此我們提供了兩個類:
iterator_range 類以一個 前向遍歷迭代器
為模板參數,用於適合的泛型代碼所需要的地方。sub_range 類則以一個 前向區間
為模板參數,通用性稍差,但是更易於使用,因為它的模板參數更容易指定。兩者之間的最大差別在於,sub_range
可以傳播常量性,因為它知道對應的 const_iterator 是什麼。
這兩個類都可用作區間,因為它們實現了可自動工作所要求的 最小接口。
iterator_rangeiterator_range 類的目的是封裝兩個迭代器,讓它們實現 前向區間 的概念。另外為了方便使用,還提供了幾個其它函數。
如果模板參數不符合前向遍歷迭代器,你還可以使用該接口的子集。例如,size() 要求前向遍歷迭代器,而
empty() 只要求單遍迭代器。
由於許多缺省構造的迭代器都是異常的,只能用於賦值而不能進行比較、遞增或其它操作。同樣,如果你創建一個缺省構造的
iterator_range, 那麼就必須小心不要做除了複製以外的任何動作。
namespace boost {
template< class ForwardTraversalIterator >
class iterator_range
{
public: // 前向區間類型
typedef ForwardTraversalIterator iterator;
typedef ForwardTraversalIterator const_iterator; typedef iterator_difference<iterator>::type difference_type; public: // 構造,賦值
template< class ForwardTraversalIterator2 >
iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );
template< class ForwardRange >
iterator_range( ForwardRange& r );
template< class ForwardRange >
iterator_range( const ForwardRange& r );
template< class ForwardRange >
iterator_range& operator=( ForwardRange& r );
template< class ForwardRange >
iterator_range& operator=( const ForwardRange& r );
public: // 前向區間函數
iterator begin() const;
iterator end() const;
difference_type size() const;
bool empty() const;
public: // 工具
operator unspecified_bool_type() const;
bool equal( const iterator_range& ) const; reference front() const; reference back() const; iterator_range& advance_begin( difference_type n ); iterator_range& advance_end( difference_type n ); // 僅用於隨機訪問區間: reference operator[]( difference_type at ) const; value_type operator()( difference_type at ) const; };
// 流輸出
template< class ForwardTraversalIterator, class T, class Traits >
std::basic_ostream<T,Traits>&
operator<<( std::basic_ostream<T,Traits>& Os,
const iterator_range<ForwardTraversalIterator>& r );
// 比較 template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
bool operator==( const iterator_range<ForwardTraversalIterator>& l,
const iterator_range<ForwardTraversalIterator2>& r );
template< class ForwardTraversalIterator, class ForwardRange >
bool operator==( const iterator_range<ForwardTraversalIterator>& l,
const ForwardRange& r );
template< class ForwardTraversalIterator, class ForwardRange >
bool operator==( const ForwardRange& l,
const iterator_range<ForwardTraversalIterator>& r );
template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
bool operator!=( const iterator_range<ForwardTraversalIterator>& l,
const iterator_range<ForwardTraversalIterator2>& r );
template< class ForwardTraversalIterator, class ForwardRange >
bool operator!=( const iterator_range<ForwardTraversalIterator>& l,
const ForwardRange& r );
template< class ForwardTraversalIterator, class ForwardRange >
bool operator!=( const ForwardRange& l,
const iterator_range<ForwardTraversalIterator>& r );
template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
bool operator<( const iterator_range<ForwardTraversalIterator>& l,
const iterator_range<ForwardTraversalIterator2>& r );
template< class ForwardTraversalIterator, class ForwardRange >
bool operator<( const iterator_range<ForwardTraversalIterator>& l,
const ForwardRange& r );
template< class ForwardTraversalIterator, class ForwardRange >
bool operator<( const ForwardRange& l,
const iterator_range<ForwardTraversalIterator>& r ); // 外部構造
template< class ForwardTraversalIterator >
iterator_range< ForwardTraversalIterator >
make_iterator_range( ForwardTraversalIterator Begin,
ForwardTraversalIterator End );
template< class ForwardRange >
iterator_range< typename range_iterator<ForwardRange>::type >
make_iterator_range( ForwardRange& r );
template< class ForwardRange >
iterator_range< typename range_iterator<const ForwardRange>::type >
make_iterator_range( const ForwardRange& r );
template< class Range > iterator_range< typename range_iterator<Range>::type > make_iterator_range( Range& r,
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end );
template< class Range > iterator_range< typename range_iterator<const Range>::type > make_iterator_range( const Range& r,
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end ); // 工具
template< class Sequence, class ForwardRange >
Sequence copy_range( const ForwardRange& r );
} // namespace 'boost'
如果一個 iterator_range 實例是由用戶以兩個迭代器構造的,用戶必須確保這兩個迭代器界定了一個有效的半開閉區間
[begin,end).
值得注意的是,模板構造函數和賦值操作符允許從 iterator_range<iterator> 轉換為
iterator_range<const_iterator>.
類似的,由於比較操作符有兩個模板參數,所以我們可以對區間進行比較,只要其迭代器是可比較的;例如,在我們處理同一個容器的常量和非常量迭代器時。
operator unspecified_bool_type() const;
返回 !empty();
bool equal( iterator_range& r ) const;
返回 begin() == r.begin() && end() == r.end();
bool operator==( const ForwardRange1& l, const ForwardRange2& r );
返回 size(l) != size(r) ? false : std::equal( begin(l), end(l), begin(r) );
bool operator!=( const ForwardRange1& l, const ForwardRange2& r );
返回 !( l == r );
bool operator<( const ForwardRange1& l, const ForwardRange2& r );
返回 std::lexicographical_compare( begin(l), end(l), begin(r), end(r) );
iterator_range make_iterator_range( Range& r,
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end );
作用:iterator new_begin = begin( r ),
iterator new_end = end( r );
std::advance( new_begin, advance_begin );
std::advance( new_end, advance_end );
return make_iterator_range( new_begin, new_end );
Sequence copy_range( const ForwardRange& r );
返回 Sequence( begin(r), end(r) );
sub_rangesub_range 類從 iterator_range
類繼承了所有功能。sub_range 類更易於使用,因為你要給出的模板參數是一個 前向區間 而不是一個迭代器。此外,sub_range
類可以傳播常量性,因為它知道對應的 const_iterator 是什麼。
namespace boost {
template< class ForwardRange >
class sub_range : public iterator_range< typename range_iterator<ForwardRange>::type >
{
public: typedef typename range_iterator<ForwardRange>::type iterator; typedef typename range_iterator<const ForwardRange>::type const_iterator; typedef typename iterator_difference<iterator>::type difference_type; public: // 構造,賦值
template< class ForwardTraversalIterator >
sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
template< class ForwardRange2 >
sub_range( ForwardRange2& r );
template< class ForwardRange2 >
sub_range( const ForwardRange2& r );
template< class ForwardRange2 >
sub_range& operator=( ForwardRange2& r );
template< class ForwardRange2 >
sub_range& operator=( const ForwardRange2& r );
public: // 前向區間函數
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
public: // 工具
value_type& front(); const value_type& front() const; value_type& back(); const value_type& back() const; // 僅用於隨機訪問區間: value_type& operator[]( difference_type at ); const value_type& operator[]( difference_type at ) const; public:
// 其它接口繼承自iterator_range};
} // namespace 'boost'
這個類的用法非常簡單,請看下文。設想我們有一個算法,在一個字符串中查找子字符串。結果是一個 iterator_range,
界定了匹配的子串。我們需要保存該算法的結果。下面的例子示範了在如何使用或不用 sub_range 來實現:
std::string str("hello"); iterator_range<std::string::iterator> ir = find_first( str, as_literal("ll") ); sub_range<std::string> sub = find_first( str, as_literal("ll") );
© Copyright Thorsten Ottosen 2008.
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)