boost库区间range基本原理及使用实例
由 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::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。
语法:
|
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可以被定义成如下类型:
* 如果__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基本原理及使用实例的更多相关文章
- boost库的安装,使用,介绍,库分类
1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...
- C++ | boost库 类的序列化
是的,这是今年的情人节,一篇还在研究怎么用的文章,文结的时候应该就用成功了. 恩,要有信心 神奇的分割线 不知何时装过boost库的header-only库, 所以ratslam中的boost是可以编 ...
- Boost库实现线程池学习及线程实现的异步调用
A.Boost线程池实现 参考自: Boost库实现线程池实例 原理:使用boost的thread_group存储多个线程,使用bind方法将要处理的函数转换成线程可调用的函数进行执行:使用队列存储待 ...
- Python和C|C++的混编(一):Python调用C、C++---Boost库
不使用boost.python库来直接构建dll的话比较繁琐,下面实例是借助boost库实现python对C.C++的调用 1 首先确定已经安装python和boost库,本例测试环境是python2 ...
- (三)Boost库之字符串处理
(三)Boost库之字符串处理 字符串处理一直是c/c++的弱项,string_algo库很好的弥补了这一点. string_algo 库算法命名规则: 前缀i : 有这个前缀表名算法的大小写不 ...
- (九)boost库之文件处理filesystem
(九)boost库之文件处理filesystem filesystem库是一个可移植的文件系统操作库,它在底层做了大量的工作,使用POSIX标准表示文件系统的路径,使C++具有了类似脚本语言的功能 ...
- (五)boost库之随机数random
(五)boost库之随机数random boost库为我们提供了许多的日常随机数生成器: 1.uniform_smallint:在小整数域内的均匀分布 2.uniform_int:在整数域上的均匀分布 ...
- (七)boost库之单例类
(七)boost库之单例类 一.boost.serialzation的单件实现 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一 ...
- (一)boost库之日期、时间
(一)boost库之日期.时间 一.计时器 计时器,通常在一个项目中统计一个函数的执行时间是非常实用的. #include <boost/timer.hpp> void PrintU ...
随机推荐
- Python3向网页POST数据
还是以我的网页iciba为例 POST数据到www.selflink.cn/iciba/get0.php获取返回的查询结果 #coding:utf8 import urllib.request imp ...
- github 坑爹的仓库初始化设置
一段时间没有使用 github,奇妙地发现自己连仓库都不会建了,汗一个... 话说上次我在 github 上面建了一个仓库,在创建仓库的设置表单中勾上了自动生成 README.md 选项, ok,创建 ...
- 怎样拷贝整个目录并且忽略部分文件及目录(包括windows)
http://www.dewen.org/q/2150 rsync -a --exclude dir1 --exclude dir2 ... source target
- iOS小结
一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始等待用户的操作,自动释放 ...
- POJ 3169 Layout(差分约束啊)
题目链接:http://poj.org/problem? id=3169 Description Like everyone else, cows like to stand close to the ...
- php的分表分库类
<?php include 'config.php'; class Model{ //用户名 protected $user; //密码 protected $pwd; //主机 protect ...
- C#_uploadify_mvc_version
jQuery Uploadify在ASP.NET MVC3中的使用 1.Uploadify简介 Uploadify是基于jQuery的一种上传插件,支持多文件.带进度条显示上传,在项目开发中常被使用. ...
- Android广播接收者应用(电话拦截器)
一.电话拦截器应用说明 在我们输入完电话号码并拨打电话时,系统会发出一个有序广播(action="android.intent.action.NEW_OUTGOING_CALL") ...
- 小白日记42:kali渗透测试之Web渗透-SQL盲注
SQL盲注 [SQL注入介绍] SQL盲注:不显示数据库内建的报错信息[内建的报错信息帮助开发人员发现和修复问题],但由于报错信息中提供了关于系统的大量有用信息.当程序员隐藏了数据库内建报错信息,替换 ...
- poj2388解题报告(排序)
POJ 2388,题目链接http://poj.org/problem?id=2388 题意: 水题一道 给定n个数,输出中间值,可以用sort,干脆快捷. 代码: //396K 32MS #incl ...