boost::array和boost::multi_array

boost::array

Boost.Array是一个模板,需要两个模板参数,分别是数据的类型和数组的大小。

boost::array<int, 1024> temp_array;

由于是模板参数,所以数组的大小必须是一个可以在编译阶段就可以推理得到的值。定义以后,就可以正常使用了。其使用方法和std::vector较类似。

// 使用某个数字填满
temp_array.fill(1);// 迭代
for (auto temp_iter = temp_array.begin(); temp_iter != temp_array.end(); ++temp_iter) {*temp_iter = 2;
}// 取某个元素
std::cout << temp_array[2] << " " << temp_array.at(3) << std::endl;// foreach
int sum_array = 0;
for (auto temp_item : temp_array) {sum_array += temp_item;
}
std::cout << sum_array << std::endl;// 逆序遍历
for (auto temp_iter = temp_array.rbegin(); temp_iter != temp_array.rend(); ++temp_iter) {*temp_iter = (temp_iter - temp_array.rbegin());
}
std::cout << temp_array[10] << std::endl;// size和max_size只返回数组的大小。而empty只在数组大小为0时返回false,在其他时候返回true
std::cout << temp_array.size() << " " << temp_array.max_size() << " " << temp_array.empty() << std::endl;

在这里插入图片描述
示例:

#include<iostream>
#include<vector>
using namespace std;
#include<boost/array.hpp>
#include<boost/progress.hpp>
using namespace  boost;const int _SIZE = 20000;template<typename T>
void test_array_task(T _int)
{// std::cout << _int << std::endl;for (int i = 0; i < _SIZE; ++i){for (int j = 0; j < _SIZE; ++j){_int[j] = j;}}
}
// 性能比较
void test_array_performance()
{// 1. 普通数组{int _int[_SIZE];boost::progress_timer pt;test_array_task<int[]>(_int);}// 2. boost::array{boost::array<int, _SIZE> a_int;boost::progress_timer pt;test_array_task<boost::array<int, _SIZE> >(a_int);}// 3. std::vector{std::vector<int> b_int;b_int.resize(_SIZE);boost::progress_timer pt;test_array_task<std::vector<int> >(b_int);}
}void test_array()
{// 1. boost::array的构造方法const int ELEMS = 6;boost::array<int, ELEMS> values1 = {3, 1, 4, 2, 9, 8};boost::array<int, ELEMS> values2 = {2, 2, 2};boost::array<int, ELEMS> values3(values1);for(size_t i = 0; i < values3.size(); i++)cout << values3[i] << " " ;cout << endl;boost::array<int, ELEMS> values4 = values2;boost::array<int,6>::iterator itr = values4.begin();for(;itr != values4.end();++itr)cout << *itr << " " ;cout << endl;int ar[] = {9, 8, 7, 1, 2, 3, 6, 4, 5};// 2. boost::array可以获取数组的长度.// 而std::array却没有这个功能, 要用sizeof(array)/sizeof(value_type)来代替boost::array<int, ELEMS>::size_type num = values2.size();            // 6boost::array<int, ELEMS>::size_type maxnum = values2.max_size();    // 6cout << "values2: " << num << " " << maxnum << endl;int arsize = sizeof(ar)/sizeof(int);    // 9cout << "arsize: " << arsize << endl;// 3. 越界异常// at: 可以用try..catch方法, 获取抛出的异常.// []: 会抛出assert错误try{values1.at(10) = 10;}catch (std::exception& e){std::cout << e.what() << std::endl;}// 抛出assert错误// values1[10];// 4. begin, cbegin, end, cend, front, end等容器的函数均可用std::copy(values1.cbegin(), values1.cend(), std::ostream_iterator<int>(std::cout, " "));std::cout << std::endl;int i1 = values1.front();int i2 = values1.back();assert(i1 == 3);assert(i2 == 8);// 5. 整体操作数据很方便values4.assign(66);
}int main()
{test_array();test_array_performance();
}

boost::multi_array

对于array,除了第一维,其它维的大小都必须是编译期确定的,N2,N3,N4必须都是编译期常量,只有n1可以是变量,这个限制与多维数组的索引方式有关——无论多少维的数组都是线性存储在内存中的

int* pOneDimArr = new int[10]; //新建一个10个元素的一维数组
pOneDimArr[0] = 0; //访问int** pTwoDimArr = new int[10][20]; //错误!
int (*pTwoDimArr)[20] = new int[i][20]; //正确
pTwoDimArr[0][0] = 0; //访问int (*pNdimArr)[N2][N3][N4] = new int[n1][N2][N3][N4];

对于

 pTwoDimArr[i][j] = 0;被编译器生成的代码类似于:*( (int*)pTwoDimArr+i*20+j ) = 0;

20就是二维数组的行宽,问题在于,如果允许二维数组的行宽也是动态的,这里编译器就无法生成代码(20所在的地方应该放什么呢?)。基于这个原因,C++只允许多维数组的第一维是动态的。

boost::multi_array 是一个需要两个参数的模板:第一个参数是要存储在数组中的元素的类型。第二个参数确定数组应该有多少维,第二个参数只设置维度的数量,而不是每个维度中的元素数量。boost::extents[3][4][2]的意思是:定义一个342的三维数组。

boost::extents[3][4][2]展开为操作符调用的方式就相当于:

extents.operator .operator .operator ;

extents的工作方式:每调用一次operator [],都会返回一个extent_gen<NumRange+1>类型的对象,所以,对于boost::extents[3][4][2],依次返回的是:extent_gen<1> => extent_gen<2> => extent_gen<3>

最后一个也是最终的返回类型——extent_gen<3>。其成员ranges_中,共有[0,3)、[0,4)、[0,2)三组区间。这三组区间指定了multi_array对象的三个维度的下标区间,值得注意的是这些区间都是前闭后开的,即不包含上界值,这一点在后面的代码中能够看到。当boost::extents准备完毕后,就被传入multi_array的构造函数,用于指定各维的下标区间

关于boost::extents,可以防止用户写出错误的代码,

multi_array<int,3> A(boost::extents[3][4][2][5]); //多了一维!

无法通过编译,因为mult_array是个三维数组,而boost::extents后面却跟了四个“[]”,这显然是个错误;在语法层面,由于multi_array<int,3>的构造函数只能接受extent_gen<3>类型的参数,boost::extents[3][4][2][5]返回的却是extent_gen<4>类型的对象,于是就会产生编译错误。这种编译期的强制措施阻止了用户一不小心犯下的错误,也很清晰明了地表达(强制)了语义的需求。

boost::multi_array::array_view 是一个模板,它将视图中的维数作为模板参数。对于示例,视图的维数为 1。由于数组 a 有两个维度,因此忽略了一个维度。为了省去Boost这个词,一维数组就足够了;更多的维度会令人困惑。
与 boost::multi_array 一样,维数作为模板参数传入,每个维的大小在运行时设置。但是,对于 boost::multi_array::array_view,这不是通过 boost::extents 完成的。相反,它是通过 boost::indices 完成的,这是 Boost.MultiArray 提供的另一个全局对象。
与 boost::extents 一样,索引必须传递给 boost::indices。虽然只能将数字传递给 boost::extents,但 boost::indices 也接受范围。这些是使用 boost::multi_array_types::index_range 定义的。
对于第二个参数,boost::multi_array_types::index_range 用于定义范围。通过将 0 和 5 传递给构造函数,a 的第一个维度的前五个元素可用。范围从索引 0 开始,到索引 5 结束——不包括索引 5 处的元素。第一维中的第六个元素被忽略。

示例:

#include <boost/multi_array.hpp>
#include <iostream>
#include <cstring>
int main()
{boost::multi_array<char, 2> a{boost::extents[2][6]};typedef boost::multi_array<char, 2>::array_view<1>::type array_view;typedef boost::multi_array_types::index_range range;array_view view = a[boost::indices[0][range{0, 5}]];std::memcpy(view.origin(), "tsooB", 6);std::reverse(view.begin(), view.end());std::cout << view.origin() << '\n';boost::multi_array<char, 2>::reference subarray = a[1];std::memcpy(subarray.origin(), "C++", 4);std::cout << subarray.origin() << '\n';
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/100447.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——线性数据结构(数组,链表,栈,队列)

文章目录 1. 数组2. 链表2.1. 链表简介2.2. 链表分类2.2.1. 单链表2.2.2. 循环链表2.2.3. 双向链表2.2.4. 双向循环链表 2.3. 应用场景2.4. 数组 vs 链表 3. 栈3.1. 栈简介3.2. 栈的常见应用常见应用场景3.2.1. 实现浏览器的回退和前进功能3.2.2. 检查符号是否成对出现3.2.3. 反…

QT VS编译环境无法打开包括文件type_traits

这问题&#xff0c;别人给的处理方法都是&#xff1a; 添加环境变量执行vsvars32.bat/vcvarsall.bat/vsdevcmd.bat重新安装QT项目&#xff1a;执行qmake。。。。 个人不推荐配置环境编译&#xff0c;除非你非常熟&#xff0c;因为配置环境变量需要你知道有哪些路径需要添加&a…

手机自动无人直播,实景无人直播真的有用吗?

继数字人直播之后&#xff0c;手机自动直播开始火热了起来&#xff0c;因为其门槛低&#xff0c;成本低&#xff0c;一部手机一个账号就可以实现直播&#xff0c;一时深受广大商家的好评。那么&#xff0c;手机自动无人直播究竟是如何实现自动直播的呢&#xff1f; 在传统的直…

视频集中存储/云存储/磁盘阵列EasyCVR平台接入RTSP设备出现离线情况的排查

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

SAP LTMC基础教程之物料主数据详细操作示例

SAP LTMC基础教程之物料主数据详细操作示例 SAP S/4HANA 1610版本的推出已经不再建议使用LSMW了&#xff0c;使用中会受到很多限制&#xff08;比如特性、类的导入&#xff09;&#xff0c;而是推出了新工具LTMC。记录并分享LTMC的操作。 有几个注意点能够搞明白基本都能成功…

数据结构——B-树、B+树、B*树

一、B-树 1. B-树概念 B树是一种适合外查找的、平衡的多叉树。一棵m阶&#xff08;m>2&#xff09;的B树&#xff0c;是一棵平衡的M路平衡搜索树&#xff0c;它可以是空树或满足以下性质&#xff1a; &#xff08;1&#xff09;根节点至少有两个孩子。 &#xff08;2&#…

Qt关于hex转double,或者QByteArray转double

正常的00 ae 02 33这种类型的hex数据类型可以直接通过以下代码进行转换 double QDataConversion::hexToDouble(QByteArray p_buf) {double retValue 0;if(p_buf.size()>4){QString str1 byteArrayToHexStr(p_buf.mid(0,1));QString str2 byteArrayToHexStr(p_buf.mid(1,…

香蕉派社区推出带10G SFP+ 端口的Banana Pi BPI-R4 Wifi7开源路由器

香蕉派BPI-R4 根据著名Banana Pi品牌背后的公司Sinovoip提供的初步信息&#xff0c;他们即将推出的Banana Pi BPI-R4路由器板目前正在开发中。与之前的 Banana Pi R3 板相比&#xff0c;这在规格上将有显着提升。这就是我们目前所知道的。 您可以选择 R4 板的两种不同配置。具…

MySQL数据库的操作

目录 创建数据库字符集和校验规则查看系统默认字符集以及校验规则校验规则对数据库的影响 操纵数据库查看已经创建的数据库显示某个数据库的创建语句修改数据库删除数据库 数据库备份和还原备份还原 查看连接情况 创建数据库 语法: create database [if not exists] 数据库名字…

二、SQL,如何实现表的创建和查询

1、新建表格&#xff08;在当前数据库中新建一个表格&#xff09;&#xff1a; &#xff08;1&#xff09;基础语法&#xff1a; create table [表名]( [字段:列标签] [该列数据类型] comment [字段注释], [字段:列标签] [该列数据类型] comment [字段注释], ……&#xff0c…

java可变字符串

一、常用方法 以StringBuilder为例 1、append(String str) 添加 StringBuilder str new StringBuilder("hello"); System.out.println(str);//在源字符串后添加world StringBuilder add str.append("world"); System.out.println(add);//结果helloworl…

大数据时代,个人信息数据库保护的挑战及其对策

挑战&#xff1a; 数据泄露&#xff1a;大数据时代&#xff0c;个人信息数据库面临被黑客攻击、内部员工滥用权限等风险&#xff0c;导致个人信息泄露的风险增加。 隐私保护&#xff1a;随着大数据的快速发展&#xff0c;个人信息的采集和分析变得更加广泛和深入。但是&#xf…

kaggle注册不显示验证码

edge浏览器 1.点击浏览器右上角三个点 2.点击扩展 3.点击管理扩展 4.点击获取Microsoft Edge扩展&#xff0c;在左上角输入Head Editor 5.输入https://www.azurezeng.com/static/HE-GoogleRedirect.json 6.下载后&#xff0c;点保存 成功&#xff01;

天锐绿盾安全U盘系统

安全U盘系统 01 简介 天锐绿盾安全U盘系统&#xff0c;是一款致力于保障U盘数据内容安全的产品。通过严格身份认证、便捷安全的密保机制、智能的U盘锁定或自毁设置、详细的文件操作日志、文件粉碎、设置还原等&#xff0c;天锐绿盾安全U盘系统为您U盘的数据保驾护航&#xff0…

onvif中imaging setting图像画质总结!

前言&#xff1a; 大家好&#xff0c;今天给大家来分享一篇关于图像质量的内容&#xff0c;这个内容是我在做onvif中的imaging setting的时候&#xff0c;关注到里面有关于: brightness(亮度)color saturation(色彩饱和度)contrast(对比度)sharpness(锐度)white balance(白平衡…

素材准备——准备用于标注和训练的图片素材——从视频监控视频中生成图片素材

为了实现我们对特定场景下的图像识别功能,我们需要依托YOLO V8工具,对大量的图片进行目标标准和训练。因此我们首先要做的一项工作便是准备大量的用于标准和训练做续的图片。 由于在实际项目中,特别是以公安交管所需要的场景中,我们很难单纯依托网络下载的方式获得所需要的…

Java 实现证件照底图替换,Java 实现照片头像底图替换

效果图 这里前端用layui实现的案例截图 color底图颜色可以在网页上这样取色 new Color(34, 133, 255) 实现案例下载链接&#xff1a;https://download.csdn.net/download/weixin_43992507/88237432

Web 3.0 安全风险,您需要了解这些内容

随着技术的不断发展&#xff0c;Web 3.0 正在逐渐成为现实&#xff0c;为我们带来了许多新的机遇和挑战。然而&#xff0c;与任何新技术一样&#xff0c;Web 3.0 也伴随着一系列安全风险&#xff0c;这些风险需要被认真对待。在这篇文章中&#xff0c;我们将探讨一些与Web 3.0 …

基于QT4的GPX文件编辑器开发

GPX文件是记录地理点的文件,本质是一种xml文件。GPX文件目前没有很好的编辑器,因此作者决定开发一款无需安装的绿色编辑器。 在QT4开发中,XML可以用DOM来实现,但其逻辑并不是很清晰。使用模型视图反而会更加可读。因此在开发中,使用model-view模式来实现数据读写。 1 需…