由 www.169it.com 搜集整理html
区间的概念相似于STL中的容器概念。一个区间提供了能够访问半开放区间[first,one_past_last)中元素的迭代器,还提供了区间中的元素数量的信息。算法
引入区间概念的目的在于:有不少相似于容器的类型,以及用于这些类型的简化算法。express
实例代码:数组
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::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"
));
}
|
类型变化:函数
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_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-for是C++ 11新增特性,用于循环迭代一个“范围”,该“范围”相似于包含有begin()和end()方法的STL序列容器。全部的STL标准容器都适用于该“范围”,例如vector、string等等。数组也一样能够,只要定义了begin()和end()方法的任何“范围”均可以使用for来循环迭代容器里面的元素,如istream。oop
语法:spa
1
|
for
( range_declaration : range_expression) loop_statement
|
上述代码的效果相似于:指针
1
2
3
4
5
6
7
8
9
|
(__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能够被定义成以下类型:code
* 若是__range是数组,(__range) 和 (__range + __bound)表示数组的范围orm
*若是__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()的方法,固然会编译不经过。
以上内容根据我的理解结合互联网上相关做者介绍总结,错误再所不免。