Boost.Range

簡介

當前的泛型算法是依據兩個或多個迭代器來工作的。兩個迭代器一起形成了算法所操作的值的區間。這種方法是一種非常通用的接口,但是使用算法時也有點麻煩,常常要重複指定容器的名字。因此我們希望提升算法的抽像層次,使它們盡可能以 Ranges區間 來指定接口。

我們最常見的區間形式是標準庫的容器。不過,你會發現還應該對代碼進行擴展以用於其它提供了足夠功能以滿足泛型代碼的需要的類型,只要提供一個合適的間接層。例如,裸數組常常可以與用於容器的泛型代碼一起使用,只要使用一個適合的適配器。

因此這個庫提供了對近似於標準的容器、以空字符結束的字符串、迭代器的 std::pairs,以及裸數組(及其它)進行改編的方法,以便同一段泛型代碼可以和它們一起使用。基本的想法是用 元函數 和獨立的函數增加一個間接層,以去除語法和/或語義上的差別。

主要的好處有:

下面給出一個簡短的例子(完整的例子代碼請見 這裡 ):


    //
    // 例子:在泛型算法中取出邊界
    //
    template< class ForwardReadableRange, class T >
inline typename boost::range_iterator< ForwardReadableRange >::type
find( ForwardReadableRange& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}

template< class ForwardReadableRange, class T >
inline typename boost::range_const_iterator< ForwardReadableRange >::type
find( const ForwardReadableRange& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}

//
// 替代第一個值並返回其索引
//
template< class ForwardReadableWriteableRange, class T >
inline typename boost::range_size< ForwardReadableWriteableRange >::type
my_generic_replace( ForwardReadableWriteableRange& c, const T& value, const T& replacement )
{
typename boost::range_iterator< ForwardReadableWriteableRange >::type found = find( c, value );

if( found != boost::end( c ) )
*found = replacement;
return std::distance( boost::begin( c ), found );
}

//
// 用法
//
const int N = 5;
std::vector<int> my_vector;
int values[] = { 1,2,3,4,5,6,7,8,9 };
my_vector.assign( values, boost::end( values ) ); typedef std::vector<int>::iterator iterator;
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
boost::begin( my_vector ) + N );
char str_val[] = "a string";
char* str = str_val;

std::cout << my_generic_replace( my_vector, 4, 2 );
std::cout << my_generic_replace( my_view, 4, 2 );
std::cout << my_generic_replace( str, 'a', 'b' );
// 打印出 '3', '5' 和 '0'
通過使用獨立函數和 元函數,這些代碼可以自動用於本庫支持的所有類型;現在以及將來。注意,我們必須提供兩個版本的 find(),因為我們不能將一個非常量右值前轉到引用參數(有關 前轉的問題,請見這篇文章)。


© 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)