当前位置:  编程语言>c/c++

boost库区间range基本原理及使用实例

 
    发布时间:2013-6-30  


    本文导语: 区间的概念类似于STL中的容器概念。一个区间提供了可以访问半开放区间[first,one_past_last)中元素的迭代器,还提供了区间中的元素数量的信息。 引入区间概念的目的在于:有很多类似于容器的类型,以及用于这些类型的简化算...


区间的概念类似于STL中的容器概念。一个区间提供了可以访问半开放区间[first,one_past_last)中元素的迭代器,还提供了区间中的元素数量的信息

引入区间概念的目的在于:有很多类似于容器的类型,以及用于这些类型的简化算法

实例代码:

void test_range_construct_string()
 {
    typedef std::string::iterator   iterator;
    typedef std::string::const_iterator const_iterator;
    typedef boost::iterator_range<iterator>   irange;
    typedef boost::iterator_range<const_iterator> cirange;
    std::string       str  = "hello world";
    const std::string cstr = "const world";
                                                                                                
    // 1. 基本构建方法
    boost::iterator_range<std::string::iterator> ir(str);
    boost::iterator_range<std::string::const_iterator> cir(str);
    // 2. 利用make_iterator_range(几种重载函数)
    irange r    = boost::make_iterator_range(str);
    r           = boost::make_iterator_range(str.begin(), str.end());
    cirange r2  = boost::make_iterator_range(cstr);
    r2          = boost::make_iterator_range(cstr.begin(), cstr.end());
    r2          = boost::make_iterator_range(str);
    assert(r == str);
    assert(r.size() == 11);
    irange r3   = boost::make_iterator_range(str, 1, -1);
    assert(boost::as_literal("ello worl") == r3);
    irange r4   = boost::make_iterator_range(r3, -1, 1);    // 这个也可以理解成复制构造
    assert(str == r4);
    std::cout << r4 << std::endl;
    irange r5 = boost::make_iterator_range(str.begin(), str.begin() + 5);
    assert(r5 == boost::as_literal("hello"));
 }

类型变化:

void test_range_type()
 {
    using namespace boost;
    // 数组
    const int SIZE = 9;
    typedef int array_t[SIZE];
    const array_t ca = {1, 2, 3, 4, 5, 6, 7, 8, 10};
    assert((is_same<range_iterator<array_t>::type,       int*          >::value));
    assert((is_same<range_value<array_t>::type,             int           >::value));
    assert((is_same<range_difference<array_t>::type,     std::ptrdiff_t>::value));
    assert((is_same<range_size<array_t>::type,           std::size_t   >::value));
    assert((is_same<range_const_iterator<array_t>::type, const int*    >::value));
    assert(begin(ca) == ca);
    assert(end(ca) == ca + size(ca));
    assert(empty(ca) == false);
 }

range-forc++ 11新增特性,用于循环迭代一个“范围”,该“范围”类似于包含有begin()和end()方法的stl序列容器。所有的stl标准容器都适用于该“范围”,例如vectorstring等等。数组也同样可以,只要定义了begin()和end()方法的任何“范围”都可以使用for来循环迭代容器里面的元素,如istream

语法

for ( range_declaration : range_expression) loop_statement

上述代码的效果类似于:

(__range, __begin and __end are for exposition only):
{    auto && __range = range_expression ;  
for (auto __begin = begin_expr, __end = end_expr;           
__begin != __end; ++__begin)  
{      
range_declaration = *__begin;      
loop_statement     
}
}


迭代器begin_expr和end_expr可以被定义成如下类型:

* 如果__range是数组,(__range) 和 (__range + __bound)表示数组的范围

*如果__range是一个,实现了begin()或end()方法,或者两个方法都实现了,此时begin_expr就表示 __range.begin(),而 end_expr则表示 __range.end()。

否则begin(__range)和end(__range)将通过基于与std名称空间关联的参数依赖查找规则来查找。

如果range_expression返回一个临时变量,它的生命周期到循环结束,如绑定到右值__range的,但要注意,临时嵌套在range_expression中的并没有延长其生命周期。

如同传统的for语句,关键字break可以提前结束循环,而continue可以继续循环。

example:

void f(vector<double>& v)
 {    for (auto x : v)
      cout << x << '/n';
      for (auto& x : v) ++x;    // 通过引用可以修改v中的值5
 }

for也可以用于迭代普通的数组,如:

for (const auto x : { 1,2,3,5,8,13,21,34 })
cout << x << '/n';

误区:

int* p = new int [2];
p[0] = 1;
p[1] = 2;
for (auto x : p)
cout << x << endl;

编译器会报错误

错误:对‘begin(int*&)’的调用没有匹配函数


通过上面对for的介绍可以知道,for实现的机制就是依赖与容器中的begin()和end()方法。对于普通的数组,编译器默认已经实现了类似的方法。这里的p是一个指针,尽管它可以像数组一样使用,但是它并没有类似与begin()或end()的方法,当然会编译不通过。

以上内容根据个人理解结合互联网上相关作者介绍总结,错误再所难免。


  • 本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.
    转载请注明:文章转载自:[169IT-IT技术资讯]
    本文标题:boost库区间range基本原理及使用实例
相关文章推荐:


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3