广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++BoostUtility超详细讲解
  • 590
分享到

C++BoostUtility超详细讲解

C++BoostUtilityC++Utility库 2022-12-08 20:12:55 590人浏览 独家记忆
摘要

目录一、说明二、Boost.Utility库示例和代码一、说明 Boost.Utility 库是杂项、有用的类和函数的集合,它们太小而无法在独立库中维护。虽然实用程序很小并且可以快速

一、说明

Boost.Utility 库是杂项、有用的类和函数的集合,它们太小而无法在独立库中维护。虽然实用程序很小并且可以快速学习,但它们完全无关。与其他章节中的示例不同,此处的代码示例不是相互构建的,因为它们是独立的实用程序。

虽然大多数实用程序都在 boost/utility.hpp 中定义,但有些实用程序有自己的头文件。以下示例包括所介绍的实用程序的相应头文件。

二、Boost.Utility库示例和代码

示例 69.1。使用 boost::checked_delete()

#include <boost/checked_delete.hpp>
#include <boost/intrusive/list.hpp>
#include <string>
#include <utility>
#include <iOStream>
struct animal : public boost::intrusive::list_base_hook<>
{
  std::string name_;
  int legs_;
 
  animal(std::string name, int legs) : name_{std::move(name)},
    legs_{legs} {}
};
int main()
{
  animal *a = new animal{"cat", 4};
  typedef boost::intrusive::list<animal> animal_list;
  animal_list al;
  al.push_back(*a);
  al.pop_back_and_dispose(boost::checked_delete<animal>);
  std::cout << al.size() << '\n';
}

Example 69.1

示例 69.1 将函数 boost::checked_delete() 作为参数传递给成员函数 pop_back_and_dispose(),该函数由 Boost.Intrusive 的类 boost::intrusive::list 提供。 boost::intrusive::list 和 pop_back_and_dispose() 在第 18 章中介绍,而 boost::checked_delete() 由 Boost.Utility 提供并在 boost/checked_delete.hpp 中定义。

boost::checked_delete() 期望作为其唯一参数的指针指向将被 delete 删除的对象。因为 pop_back_and_dispose() 需要一个函数来销毁相应的对象,所以传入 boost::checked_delete() 是有意义的——这样,您就不需要定义类似的函数。

与 delete 不同,boost::checked_delete() 确保要销毁的对象的类型是完整的。 delete 将接受指向具有不完整类型的对象的指针。虽然这涉及您通常可以忽略的 c++ 标准细节,但您应该注意 boost::checked_delete() 与调用 delete 并不完全相同,因为它对其参数提出了更高的要求。

Boost.Utility 还提供了 boost::checked_array_delete(),可用于销毁数组。它调用 delete[] 而不是 delete。

此外,boost::checked_deleter 和 boost::checked_array_deleter 这两个类可用于创建行为分别类似于 boost::checked_delete() 和 boost::checked_array_delete() 的函数对象。

示例 69.2。使用 BOOST_CURRENT_FUNCTioN

#include <boost/current_function.hpp>
#include <iostream>
int main()
{
  const char *funcname = BOOST_CURRENT_FUNCTION;
  std::cout << funcname << '\n';
}

Example 69.2

示例 69.2 使用在 boost/current_function.hpp 中定义的宏 BOOST_CURRENT_FUNCTION 将周围函数的名称作为字符串返回。

BOOST_CURRENT_FUNCTION 提供了一种独立于平台的方法来检索函数的名称。从 C++11 开始,您可以使用标准化宏 __func__ 做同样的事情。在 C++11 之前,Visual C++ 和 GCC 等编译器支持宏 __FUNCTION__ 作为扩展。 BOOST_CURRENT_FUNCTION 使用编译器支持的任何宏。

如果使用 Visual C++ 2013 编译,示例 69.2 显示 int __cdecl main(void)。

示例 69.3。使用 boost::prior() 和 boost::next()

#include <boost/next_prior.hpp>
#include <array>
#include <alGorithm>
#include <iostream>
int main()
{
  std::array<char, 4> a{{'a', 'c', 'b', 'd'}};
  auto it = std::find(a.begin(), a.end(), 'b');
  auto prior = boost::prior(it, 2);
  auto next = boost::next(it);
  std::cout << *prior << '\n';
  std::cout << *it << '\n';
  std::cout << *next << '\n';
}

Boost.Utility 提供了两个函数,boost::prior() 和 boost::next(),它们返回一个相对于另一个迭代器的迭代器。在示例 69.3 中,它指向数组中的“b”,prior 指向“a”,然后指向“d”。

与 std::advance() 不同,boost::prior() 和 boost::next() 返回一个新的迭代器并且不修改传入的迭代器。

除了迭代器之外,这两个函数都接受第二个参数,该参数指示向前或向后移动的步数。在示例 69.3 中,迭代器在对 boost::prior() 的调用中向后移动了两步,在对 boost::next() 的调用中向前移动了一步。

步数始终为正数,即使对于向后移动的 boost::prior() 也是如此。

要使用 boost::prior() 和 boost::next(),请包含头文件 boost/next_prior.hpp。

这两个函数都被添加到 C++11 的标准库中,它们被称为 std::prev() 和 std::next()。它们在头文件迭代器中定义。

示例 69.4。使用 boost::noncopyable

#include <boost/noncopyable.hpp>
#include <string>
#include <utility>
#include <iostream>
struct animal : boost::noncopyable
{
  std::string name;
  int legs;
  animal(std::string n, int l) : name{std::move(n)}, legs{l} {}
};
void print(const animal &a)
{
  std::cout << a.name << '\n';
  std::cout << a.legs << '\n';
}
int main()
{
  animal a{"cat", 4};
  print(a);
}

Boost.Utility 提供类 boost::noncopyable,它在 boost/noncopyable.hpp 中定义。此类使复制(和移动)对象变得不可能。

通过将复制构造函数和赋值运算符定义为私有成员函数,或者从 C++11 开始,通过使用 delete 删除复制构造函数和赋值运算符,可以达到相同的效果。然而,从 boost::noncopyable 派生明确说明类的对象应该是不可复制的。

注意:

一些开发人员更喜欢 boost::noncopyable,而其他开发人员更喜欢使用 delete 显式删除成员函数。您会在 Stack Overflow 等地方找到这两种方法的论点。

可以编译和执行示例 69.4。但是,如果将 print() 函数的签名修改为按值而不是按引用获取动物类型的对象,则生成的代码将不再编译。

示例 69.5。使用 boost::addressof()

#include <boost/utility/addressof.hpp>
#include <string>
#include <iostream>
struct animal
{
  std::string name;
  int legs;
  int operator&() const { return legs; }
};
int main()
{
  animal a{"cat", 4};
  std::cout << &a << '\n';
  std::cout << boost::addressof(a) << '\n';
}

为了检索特定对象的地址,即使运算符 & 已被重载,Boost.Utility 提供了函数 boost::addressof(),它在 boost/utility/addressof.hpp 中定义(参见示例 69.5)。在 C++11 中,此函数成为标准库的一部分,并在头文件内存中作为 std::addressof() 提供。

示例 69.6。使用 BOOST_BINARY

#include <boost/utility/binary.hpp>
#include <iostream>
int main()
{
  int i = BOOST_BINARY(1001 0001);
  std::cout << i << '\n';
  short s = BOOST_BINARY(1000 0000 0000 0000);
  std::cout << s << '\n';
}

宏 BOOST_BINARY 允许您创建二进制形式的数字。标准 C++ 仅支持十六进制和八进制形式,使用前缀 0x 和 0。C++11 引入了用户定义文字,允许您定义自定义后缀,但在 C+ 中仍然没有以二进制形式使用数字的标准方法+11。

示例 69.6 显示 145 和 -32768。 s 中存储的位序列表示一个负数,因为 16 位类型的 short 使用第 16 位——short 中的最高有效位——作为符号位。

BOOST_BINARY 只是提供了另一种写数字的选项。因为在 C++ 中,数字的默认类型是 int,所以 BOOST_BINARY 也使用 int。要定义一个 long 类型的数字,请使用宏 BOOST_BINARY_L,它生成等同于以字母 L 为后缀的数字。

Boost.Utility 包括额外的宏,例如 BOOST_BINARY_U,它初始化一个没有符号位的变量。所有这些宏都在头文件 boost/utility/binary.hpp 中定义。

示例 69.7。使用 boost::string_ref

#include <boost/utility/string_ref.hpp>
#include <iostream>
boost::string_ref start_at_boost(boost::string_ref s)
{
  auto idx = s.find("Boost");
  return (idx != boost::string_ref::npos) ? s.substr(idx) : "";
}
int main()
{
  boost::string_ref s = "The Boost C++ Libraries";
  std::cout << start_at_boost(s) << '\n';
}

Example 69.7

示例 69.7 引入了类 boost::string_ref,它是对仅支持读取访问的字符串的引用。在某种程度上,该引用可与 const std::string& 相媲美。然而,const std::string& 要求存在一个 std::string 类型的对象。 boost::string_ref 也可以在没有 std::string 的情况下使用。 boost::string_ref 的好处是,与 std::string 不同,它不需要分配内存。

示例 69.7 在字符串中查找单词“Boost”。如果找到,将显示以该词开头的字符串。如果未找到“Boost”一词,则会显示一个空字符串。 main() 中字符串 s 的类型不是 std::string,而是 boost::string_ref。因此,没有内存分配给 new,也没有创建副本。 s 直接指向文字字符串“The Boost C++ Libraries”。

start_at_boost() 的返回值类型是 boost::string_ref,而不是 std::string。该函数不返回新字符串,它返回一个引用。此引用指向参数的子字符串或空字符串。 start_at_boost() 要求原始字符串在使用 boost::string_ref 类型的引用时保持有效。如果可以保证这一点,如示例 69.7 所示,则可以避免内存分配。

还可以使用其他实用程序,但它们超出了本书的范围,因为它们主要由 Boost 库的开发人员使用或用于模板元编程。 Boost.Utility 的文档提供了这些附加实用程序的相当全面的概述,如果您有兴趣,可以作为起点。

到此这篇关于C++ Boost Utility超详细讲解的文章就介绍到这了,更多相关C++ Boost Utility内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++BoostUtility超详细讲解

本文链接: https://www.lsjlt.com/news/174549.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++BoostUtility超详细讲解
    目录一、说明二、Boost.Utility库示例和代码一、说明 Boost.Utility 库是杂项、有用的类和函数的集合,它们太小而无法在独立库中维护。虽然实用程序很小并且可以快速...
    99+
    2022-12-08
    C++ Boost Utility C++ Utility库
  • C++BoostUuid超详细讲解
    目录一、说明二、Boost.Uuid库示例和代码一、说明 Boost.Uuid 为 UUID 提供生成器。 UUID 是不依赖于中央协调实例的通用唯一标识符。例如,没有数据库存储所有...
    99+
    2022-12-08
    C++ Boost Uuid C++ Uuid标识符
  • C++超详细讲解泛型
    目录1.了解泛型编程2.函数模板2.1简单示例2.2多个模板参数2.3模板实例化2.4模板和普通函数同时存在2.5函数模板不支持定义和声明分离3.类模板3.1简单示例3.2成员函数声...
    99+
    2022-11-13
  • C++ Boost Assign超详细讲解
    目录说明Exercise说明 Boost.Assign Boost.Assign 库提供了帮助函数来初始化容器或向容器添加元素。如果需要将许多元素存储在一个容器中,这些函数尤其有用。...
    99+
    2022-12-09
    C++ Boost Assign C++ Assign库
  • C++超详细讲解标准库
    目录一、有趣的重载二、C++ 标准库三、小结一、有趣的重载 操作符 << 的原生意义是按位左移,例:1 <<2; 其意义是将整数 1 按位左移2位,即:000...
    99+
    2022-11-13
  • C++BoostPropertyTree示例超详细讲解
    目录一、提要二、应用示例练习一、提要 借助类 boost::property_tree::ptree,Boost.PropertyTree 提供了一个树结构来存储键/值对。树形结构意...
    99+
    2022-11-13
    C++ Boost PropertyTree C++ Boost PropertyTree示例
  • C++BoostVariant示例超详细讲解
    目录一、提要二、示例一、提要         Boost.Variant 提供了一个类似于 unio&...
    99+
    2022-11-13
    C++ Boost Variant C++ Boost Variant示例
  • C++BoostOptional示例超详细讲解
    目录一、概述二、Boost.Optional一、概述 数据结构类似于容器,因为它们可以存储一个或多个元素。但是,它们与容器不同,因为它们不支持容器通常支持的操作。例如,使用本部分介绍...
    99+
    2022-11-13
    C++ Boost Optional C++ Boost Optional示例
  • C++超详细讲解稀疏矩阵
    目录稀疏矩阵矩阵与稀疏矩阵的定义稀疏矩阵的转置详细思路思路一思路二稀疏矩阵的乘法详细思路稀疏矩阵 矩阵与稀疏矩阵的定义 Q:什么是矩阵 A:数学上,一个矩阵由 m 行 n 列的元素组...
    99+
    2022-11-13
  • C++超详细讲解析构函数
    目录特性析构函数处理自定义类型编译器生成的默认析构函数特性 析构函数是特殊的成员函数 特征如下: 析构函数名是~类名;无参数无返回值;一个类有且只有一个析构函数;对象声明周期结束,编...
    99+
    2022-11-13
  • C++超详细讲解构造函数
    目录类的6个默认成员函数构造函数特性编译器生成的默认构造函数成员变量的命名风格类的6个默认成员函数 如果我们写了一个类,这个类我们只写了成员变量没有定义成员函数,那么这个类中就没有函...
    99+
    2022-11-13
  • C++超详细讲解智能指针
    目录一、内存泄漏-永恒的话题二、深度思考三、智能指针分析四、小结一、内存泄漏-永恒的话题 动态申请堆空间,用完后不归还C++ 语言中没有垃圾回收的机制指针无法控制所指堆空间的生命周期...
    99+
    2022-11-13
  • C++超详细讲解函数对象
    目录一、客户需求二、存在的问题三、解决方案四、函数对象五、小结一、客户需求 编写一个函数 函数可以获得斐波那契数列每项的值每调用一次返回一个值函数可根据需要重复使用 下面来看第一个...
    99+
    2022-11-13
  • C++超详细讲解字符串类
    目录一、历史遗留问题二、解决方案三、标准库中的字符串类四、字符串循环右移五、小结一、历史遗留问题 C 语言不支持真正意义上的字符串C 语言用字符数组和一组函数实现字符串操作C 语言不...
    99+
    2022-11-13
  • C++超详细讲解函数重载
    目录1 函数重载的定义2 构成函数重载的条件3 编译器调用重载函数的准则4 函数重载的注意事项4.1 避开重载带有指定默认值参数的函数4.2 注意函数重载遇上函数指针4.3 C++编...
    99+
    2022-11-13
  • SpringCloudNetflixRibbon超详细讲解
    目录一、Ribbon简介1、什么是Ribbon2、Ribbon能干什么二、使用Ribbon1、客户端导入依赖2、application.yml配置3、Controller配置4、Co...
    99+
    2022-11-13
    SpringCloud Netflix Ribbon SpringCloud Ribbon
  • AndroidLayerDrawable超详细讲解
    目录1. 前言2. 实例1. 前言 Android LayerDrawble 包含一个Drawable数组,系统将会按照这些Drawable对象的数组顺序来绘制他们,索引最大的 Dr...
    99+
    2022-11-13
    Android LayerDrawable Android LayerDrawable原理
  • AndroidSwipeRefreshLayout超详细讲解
    目录1. 控件说明2. API介绍3. 使用方法3.1 布局文件3.2 界面代码4. 注意事项1. 控件说明 SwipeRefreshLayout是google官方推荐使用的下拉刷新...
    99+
    2022-11-13
    Android SwipeRefreshLayout Android SwipeRefreshLayout控件
  • C语言超详细讲解线性表
    目录1. 顺序表1.1 管理结点1.2 顺序表的插入1.3 顺序表的删除1.4 顺序表的扩容2. 链表2.1 定义2.2 头部插入2.3 尾部插入2.4 任意位置插入2.5 任意位置...
    99+
    2022-11-13
  • C++超详细讲解运算符重载
    目录概念赋值运算符重载const成员取地址及const取地址操作符重载概念 C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作