C++ Boost.Range与Adapters库使用详解

目录
  • 一、说明
  • 二、适配器
  • 练习

一、说明

本节叙述关于Boost.Range和Adeptor两个内容。

Boost.Range 是一个库,乍一看,它提供的算法类似于标准库提供的算法。例如,您会发现函数 boost::copy(),它的作用与 std::copy() 相同。但是, std::copy() 需要两个参数,而 boost::copy() 需要一个范围。

二、适配器

标准库提供了几种可以传递谓词的算法。例如,传递给 std::count_if() 的谓词确定计算哪些元素。 Boost.Range 提供了类似的函数 boost::count_if()。然而,这个算法只是为了完整性而提供的,因为 Boost.Range 提供了适配器,使得带有谓词的算法变得多余。

您可以将适配器视为过滤器。它们基于另一个范围返回一个新范围。数据不一定被复制。由于范围只是一对迭代器,因此适配器返回一个新的对。该对仍可用于迭代原始范围,但例如可以跳过某些元素。如果将 boost::count() 与此类适配器一起使用,则不再需要 boost::count_if()。不必多次定义算法,以便可以在有或没有谓词的情况下调用它们。

算法和适配器的区别在于算法迭代一个范围并处理数据,而适配器返回一个新的范围——新的迭代器——它决定了迭代返回的元素。但是,不执行迭代。必须首先调用算法。

示例 30.4。使用 boost::adaptors::filter() 过滤范围

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <array>
#include <iterator>
#include <iostream>
int main()
{
  std::array<int, 6> a{{0, 5, 2, 1, 3, 4}};
  boost::copy(boost::adaptors::filter(a, [](int i){ return i > 2; }),
    std::ostream_iterator<int>{std::cout, ","});
}

Example30.4

示例 30.4 使用了一个可以过滤范围的适配器。如您所见,适配器只是一个函数。 boost::adaptors::filter() 的第一个参数是要过滤的范围,第二个参数是谓词。示例 30.4 中的谓词删除范围内不大于 2 的所有数字。

boost::adaptors::filter() 不会更改范围 a,它会返回一个新范围。由于范围与一对迭代器没有太大区别,因此新范围也指的是 a.但是,新范围的迭代器会跳过所有小于或等于 2 的数字。

示例 30.4 将 5,3,4 写入标准输出。

示例 30.5。使用键()、值()和间接()

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <array>
#include <map>
#include <string>
#include <utility>
#include <iterator>
#include <iostream>
int main()
{
  std::array<int, 3> a{{0, 1, 2}};
  std::map<std::string, int*> m;
  m.insert(std::make_pair("a", &a[0]));
  m.insert(std::make_pair("b", &a[1]));
  m.insert(std::make_pair("c", &a[2]));
  boost::copy(boost::adaptors::keys(m),
    std::ostream_iterator<std::string>{std::cout, ","});
  boost::copy(boost::adaptors::indirect(boost::adaptors::values(m)),
    std::ostream_iterator<int>{std::cout, ","});
}

Example30.5

示例 30.5 使用两个适配器 boost::adaptors::keys() 和 boost::adaptors::values() 来访问 std::map 类型容器中的键和值。它还显示了如何嵌套适配器。因为 m 存储指向要打印的值的指针,而不是值本身,所以 boost::adaptors::values() 返回的范围将传递给 boost::adaptors::indirect()。当范围由指针组成时,始终可以使用此适配器,但迭代应返回指针引用的值。这就是示例 30.5 将 a、b、c、0、1、2 写入标准输出的原因。

示例 30.6。 boost::adaptors::tokenize() - 字符串适配器

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
  std::string s = "The Boost C++ Libraries";
  boost::regex expr{"[\\w+]+"};
  boost::copy(boost::adaptors::tokenize(s, expr, 0,
    boost::regex_constants::match_default),
    std::ostream_iterator<std::string>{std::cout, ","});
}

Example30.6

示例 30.6 引入了一个字符串适配器。您可以使用 boost::adaptors::tokenize() 在正则表达式的帮助下从字符串中获取范围。您将一个字符串和一个 boost::regex 类型的正则表达式传递给 boost::adaptors::tokenize()。此外,您需要传递一个引用正则表达式中的组的数字和一个标志。如果不使用组,则可以传递 0。标志 boost::regex_constants::match_default 选择正则表达式的默认设置。您还可以传递其他标志。例如,如果您希望根据编程语言 Perl 的规则应用正则表达式,则可以使用 boost::regex_constants::match_perl。

练习

创建一个程序,将 0 到 100 之间的所有奇数按升序写入标准输出。仅使用来自 Boost.Range 的算法——没有手动循环。

到此这篇关于C++ Boost.Range与Adapters库使用详解的文章就介绍到这了,更多相关C++ Boost.Range与Adapters库内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++ Boost Graph算法超详细精讲

    Boost.Graph 中的算法类似于标准库中的算法——它们是通用的并且非常灵活.但是,并不总是很清楚应该如何使用它们. 示例 31.8.使用breadth_first_search() 从内到外访问点 #include <boost/graph/adjacency_list.hpp> #include <boost/graph/breadth_first_search.hpp> #include <boost/graph/named_function_params.hpp&

  • C++ Boost Heap使用实例详解

    目录 一.说明Boost.Heap 二.功能示例 一.说明Boost.Heap Boost.Heap 也可以称为 Boost.PriorityQueue,因为该库提供了几个优先级队列.但是,Boost.Heap 中的优先级队列与 std::priority_queue 不同,它支持更多功能. 二.功能示例 示例 17.1.使用 boost::heap::priority_queue #include <boost/heap/priority_queue.hpp> #include <io

  • C++ Boost Algorithm算法超详细精讲

    目录 一.说明Boost.Algorithm 二.示例 练习 一.说明Boost.Algorithm Boost.Algorithm 请注意,其他 Boost 库提供了许多算法.例如,您会在 Boost.StringAlgorithms 中找到处理字符串的算法. Boost.Algorithm 提供的算法不受特定类的约束,例如 std::string.与标准库中的算法一样,它们可以与任何容器一起使用. 二.示例 示例 29.1.使用 boost::algorithm::one_of_equal(

  • C++ Boost CircularBuffer算法超详细精讲

    提要 库 Boost.CircularBuffer 提供了一个循环缓冲区,它是一个具有以下两个基本属性的容器: 循环缓冲区的容量是恒定的,由您设置.当您调用成员函数(例如 push_back())时,容量不会自动更改.只有您可以更改循环缓冲区的容量.循环缓冲区的大小不能超过您设置的容量. 尽管容量不变,但您可以随时调用 push_back() 将元素插入循环缓冲区.如果已达到最大大小并且循环缓冲区已满,则将覆盖元素. 当可用内存量有限并且您需要防止容器任意增长时,循环缓冲区是有意义的.另一个例子

  • C++ Boost MultiArray简化使用多维数组库

    目录 一.介绍Boost.MultiArray 二.示例 一.介绍Boost.MultiArray Boost.MultiArray Boost.MultiArray 是一个简化使用多维数组的库.最重要的优点是多维数组可以像标准库中的容器一样使用.例如,有一些成员函数,例如 begin() 和 end(),让您可以通过迭代器访问多维数组中的元素.迭代器比通常用于 C 数组的指针更易于使用,尤其是对于具有多个维度的数组. 二.示例 示例 19.1.带有 boost::multi_array 的一维

  • C++ Boost Intrusive库示例精讲

    目录 一.说明 二.示例 一.说明 Boost.Intrusive 是一个特别适合在高性能程序中使用的库.该库提供了创建侵入式容器的工具.这些容器替换了标准库中的已知容器.它们的缺点是它们不能像 std::list 或 std::set 那样容易使用.但它们有以下优点: 侵入式容器不会动态分配内存.对 push_back() 的调用不会导致使用 new 进行动态分配.这是侵入式容器可以提高性能的一个原因. 侵入式容器不会动态分配内存.对 push_bacIntrusive 容器的调用存储原始对象

  • C++ Boost Bimap示例详细讲解

    目录 一.提要 二.示例 练习 一.提要 库 Boost.Bimap 基于 Boost.MultiIndex 并提供了一个无需先定义即可立即使用的容器.该容器类似于 std::map,但支持从任一侧查找值. Boost.Bimap 允许您根据访问地图的方式创建任意一侧都可以作为关键点的地图.当您访问左侧作为键时,右侧是值,反之亦然. 二.示例 Example13.1.Usingboost::bimap #include <boost/bimap.hpp> #include <string

  • C++ Boost.Range与Adapters库使用详解

    目录 一.说明 二.适配器 练习 一.说明 本节叙述关于Boost.Range和Adeptor两个内容. Boost.Range 是一个库,乍一看,它提供的算法类似于标准库提供的算法.例如,您会发现函数 boost::copy(),它的作用与 std::copy() 相同.但是, std::copy() 需要两个参数,而 boost::copy() 需要一个范围. 二.适配器 标准库提供了几种可以传递谓词的算法.例如,传递给 std::count_if() 的谓词确定计算哪些元素. Boost.

  • C++ Boost TypeTraits库使用详解

    目录 一.说明 二.库Boost.TypeTraits 一.说明 反省是重点中的重点,泛型在实践中贯穿工程的始终.以下库支持泛型编程.无需详细了解模板元编程即可使用这些库. Boost.TypeTraits 提供了检查类型属性的函数. Boost.EnableIf 可以与 Boost.TypeTraits 一起使用,例如,根据函数的返回类型重载函数. Boost.Fusion 使创建异构容器成为可能——其元素可以具有不同类型的容器. Boost.TypeTraits Boost.EnableIf

  • Golang标准库syscall详解(什么是系统调用)

    一.什么是系统调用 In computing, a system call is the programmatic way in which a computer program requests a service from the kernel of the operating system it is executed on. This may include hardware-related services (for example, accessing a hard disk dri

  • Python heapq库案例详解

    Python heapq heapq 库是 Python 标准库之一,提供了构建小顶堆的方法和一些对小顶堆的基本操作方法(如入堆,出堆等),可以用于实现堆排序算法. 堆是一种基本的数据结构,堆的结构是一棵完全二叉树,并且满足堆积的性质:每个节点(叶节点除外)的值都大于等于(或都小于等于)它的子节点. 堆结构分为大顶堆和小顶堆,在 heapq 中使用的是小顶堆: 大顶堆:每个节点(叶节点除外)的值都大于等于其子节点的值,根节点的值是所有节点中最大的. 小顶堆:每个节点(叶节点除外)的值都小于等于其

  • C++ Boost实现数字与字符串转化详解

    目录 一.引言 二.Boost.LexicalCast 2.1 示例1 2.2 示例2 三.lexical_cast与c/c++提供类似接口的比较 3.1 两者比较 3.2 样例 一.引言 在boost库中,有一个函数Boost.LexicalCast可以将数字和字符串进行双向转换.本文介绍这种用法的案例. 二.Boost.LexicalCast Boost.LexicalCast 提供了一个转换运算符,boost::lexical_cast,它可以将数字从字符串转换为数字类型,例如 int 或

  • python中openpyxl库用法详解

    目录 一.读取数据 1.1 从工作簿中取得工作表 1.2 从表中取得单元格 1.3 从表中取得行和列 二.写入数据 2.1 创建Workbook对象来创建Excel文件并保存 2.2 案例分析一 :爬取数据并保存excel中 2.3 案例分析二: 操作单元格中内容样式并保存数据 2.4 案例分析三:将列表数据写入excel中 openpyxl模块是一个读写Excel 文档的Python库,openpyxl是一个比较综合的工具,能够同时读取和修改Excel文档. openpyxl.load_wor

  • Linux静态库与动态库实例详解

    Linux静态库与动态库实例详解 1. Linux 下静态链接库编译与使用 首先编写如下代码: // main.c #include "test.h" int main(){ test(); return 0; } // test.h #include<iostream> using namespace std; void test(); // test.c #include "test.h" void test(){ cout<< &quo

  • Python中logging日志库实例详解

    logging的简单使用 用作记录日志,默认分为六种日志级别(括号为级别对应的数值) NOTSET(0) DEBUG(10) INFO(20) WARNING(30) ERROR(40) CRITICAL(50) special 在自定义日志级别时注意不要和默认的日志级别数值相同 logging 执行时输出大于等于设置的日志级别的日志信息,如设置日志级别是 INFO,则 INFO.WARNING.ERROR.CRITICAL 级别的日志都会输出. |2logging常见对象 Logger:日志,

  • golang常用库之gorilla/mux-http路由库使用详解

    golang常用库:gorilla/mux-http路由库使用 golang常用库:配置文件解析库-viper使用 golang常用库:操作数据库的orm框架-gorm基本使用 一:golang自带路由介绍 golang自带路由库 http.ServerMux ,实际上是一个 map[string]Handler,是请求的url路径和该url路径对于的一个处理函数的映射关系.这个实现比较简单,有一些缺点: 不支持参数设定,例如/user/:uid 这种泛型类型匹配无法很友好的支持REST模式,无

  • Python 图片处理库exifread详解

    [导语]:用 python 怎样获得图片的GPS信息?今天推荐一下 exifread 这个神奇的库,不仅仅是 GPS 信息,几乎能能获得图片的所有信息,快进来看看!! 要怎样获得拍摄图片的GPS呢?这里我们需要exifread 库,这个就是用来提取 GPS 信息的.直接 pip install exifread 来安装就好了. 其实不仅能获得GPS信息,图片的几乎所有信息都能获得.exifread的作用其实是代替了查看图片属性!如下图: 这里用在三亚拍的骆驼照片来做个演示,看看能不能定位到三亚.

随机推荐