您的位置:首页 > 其它

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

2014-11-03 00:00 281 查看
由www.169it.com搜集整理
区间的概念类似于STL中的容器概念。一个区间提供了可以访问半开放区间[first,one_past_last)中元素的迭代器,还提供了区间中的元素数量的信息。
引入区间概念的目的在于:有很多类似于容器的类型,以及用于这些类型的简化算法。
实例代码:
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28
void
test_range_construct_string()


{


typedef
std::string::iteratoriterator;


typedef
std::string::const_iteratorconst_iterator;


typedef
boost::iterator_range<iterator>irange;


typedef
boost::iterator_range<const_iterator>cirange;


std::stringstr=
"helloworld"
;


const
std::stringcstr=
"constworld"
;




//1.基本构建方法


boost::iterator_range<std::string::iterator>ir(str);


boost::iterator_range<std::string::const_iterator>cir(str);


//2.利用make_iterator_range(几种重载函数)


iranger=boost::make_iterator_range(str);


r=boost::make_iterator_range(str.begin(),str.end());


ciranger2=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);


iranger3=boost::make_iterator_range(str,1,-1);


assert
(boost::as_literal(
"elloworl"
)==r3);


iranger4=boost::make_iterator_range(r3,-1,1);
//这个也可以理解成复制构造


assert
(str==r4);


std::cout<<r4<<std::endl;


iranger5=boost::make_iterator_range(str.begin(),str.begin()+5);


assert
(r5==boost::as_literal(
"hello"
));


}
类型变化:
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
void
test_range_type()


{


using
namespace
boost;


//数组


const
int
SIZE=9;


typedef
int
array_t[SIZE];


const
array_tca={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-for是C++11新增特性,用于循环迭代一个“范围”,该“范围”类似于包含有begin()和end()方法的STL序列容器。所有的STL标准容器都适用于该“范围”,例如vector、string等等。数组也同样可以,只要定义了begin()和end()方法的任何“范围”都可以使用for来循环迭代容器里面的元素,如istream。
语法:
1
for
(range_declaration:range_expression)loop_statement
上述代码的效果类似于:
1

2

3

4

5

6

7

8

9
(__range,__beginand__endare
for
expositiononly):

{
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:
1

2

3

4

5
void
f(vector<
double
>&v)


{
for
(
auto
x:v)


cout<<x<<
'/n'
;


for
(
auto
&x:v)++x;
//通过引用可以修改v中的值5


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

2
for
(
const
auto
x:{1,2,3,5,8,13,21,34})

cout<<x<<
'/n'
;
误区:
1

2

3

4

5
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()的方法,当然会编译不通过。
以上内容根据个人理解结合互联网上相关作者介绍总结,错误再所难免。

文章来源:boost库区间range基本原理及使用实例
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: