目录
双射容器bimap
基本概念
C++的STL的map和mutil_map可以把key映射到value,但是这种映射关系是单向的,然而实际项目中有一些场景,双射容器更合适。boost.bimap扩展了标准库的映射容器,提高了双向映射能力,且其设计符合STL规范。
bimap的使用代码举例
#include<boost/bimap.hpp>
void BoostTest::test_boost_bimap()
{
using boost::bimap;
using namespace std;
bimap<int, string> bi;
//实际是两个map组装 left和right 要求key-value均唯一
bi.insert({ 2, "dog" });
//左视图 key int
bi.left.insert({ 1, "cat" });
//右视图 key string
bi.right.insert({ "pig", 3 });
bi.right.insert(std::make_pair("bird", 4));
for (auto &node : bi.left)
{
std::cout << node.first << " " << node.second << std::endl;
}
for (auto &node : bi.right)
{
std::cout << node.first << " " << node.second << std::endl;
}
//查找
auto it = bi.left.find(2); //左视图的key为整形
if (it != bi.left.end())
cout << it->first << "~" << it->second << endl;
//左右视图双射容器查询
cout << bi.left.at(2) << endl;
cout << bi.right.at("dog") << endl;
auto it2 = bi.right.find("dog"); //右视图的key为字符串
if (it2 != bi.right.end())
cout << it2->first << "~" << it2->second << endl;
}

项目优化中bimap实战
boost::bimap<HIK_VEHICLE_COLOR, QString> m_bimapVehicleColor;
//...
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_OTHER, "unknown"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_WHITE, "white"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_SILVER, "silver"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_GRAY, "gray"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_BLACK, "black"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_RED, "red"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_NAVY_BLUE, "deepBlue"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_BLUE, "blue"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_YELLOW, "yellow"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_GREEN, "green"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_BROWN, "brown"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_PINK, "pink"));
m_bimapVehicleColor.left.insert(std::make_pair(ISC_VEHICLE_COLOR_PURPLE, "purple"));
//...
//第三方接口接收字段映射为枚举值
tmp = param["vehicleColor"].toString();
if (m_bimapVehicleColor.right.count(tmp) > 0)
{
vehicle.VehicleColor = (int)m_bimapVehicleColor.right.at(tmp);
}
//...
//对内枚举值映射为对外描述字符串
QString vehicleColorStr = m_bimapVehicleColor.left.at(ISC_VEHICLE_COLOR_WHITE);
多维数组
基本概念
multi_array它实现了一个通用、与标准库的容器一致的接口,并且具有与C++中内建的多维数组一样的界面和行为。正是基于这种通用性的设计,MultiArray库与标准库组件甚至用户自定义的泛型组件之间可以具有很好的兼容性,并能够很好的协同工作。
除此之外,MultiArray还提供了诸如改变大小、重塑(reshaping)以及对多维数组的视图访问等极为有用的特性,从而使MultiArray比其它描述多维数组的方式(譬如:std::vector< std::vector<...> > )更为便捷、高效。
multi_array使用代码举例
#include"boost/multi_array.hpp"
#include<boost/array.hpp>
void BoostTest::test_boost_mutil_array()
{
//运行时多维数组 c++的数组必须指定二维以上维度 int a[n][10][3]
using boost::multi_array;
int a = 2, b = 3, c = 4;//可以cin>>输入
//通过boost::extents函数创建多位数组
multi_array<int, 3>arr(boost::extents[a][b][c]);
//通过一纬固定大小数组值创建多维的纬度 2页3行4列
boost::array<int, 3>wd2 = {2,3,4};
multi_array<int, 3>arr2(wd2);
//打印数组的每一个维度
std::cout << "维度:" << arr2.num_dimensions() << ","
<< arr2.shape()[0] << "," //2
<< arr2.shape()[1] << "," //3
<< arr2.shape()[2]<<"," //4
<< "元素个数" << arr2.num_elements()<<std::endl;
for (int i = 0; i < arr2.shape()[0]; i++)
{
for (int j = 0; j < arr2.shape()[1]; j++)
{
for (int k = 0; k < arr2.shape()[2]; k++)
{
arr2[i][j][k] = i * 100 + j * 10 + k;
}
}
}
//遍历 类似图书管理 x图书室 y图区 z图书架 m层 n本 i页 j行 k列
for (int i = 0; i < arr2.shape()[0]; i++)
{
std::cout << i << "页" << std::endl;
for (int j = 0; j < arr2.shape()[1]; j++)
{
for (int k = 0; k < arr2.shape()[2]; k++)
{
std::cout << i << "页" << j << "行" << k << "列" << arr2[i][j][k]<<" ";
}
std::cout << std::endl;
}
}
//改变数组维度 原有的元素将被复制到新内存
arr2.resize(boost::extents[4][5][6]);
arr2[3][4][5] = 99;
std::cout << arr2[0][0][0] << arr2[0][1][0] << arr2[3][4][5] << std::endl;
boost::array<int, 3>wd = { 2, 5, 12 };//4*5*6 = 2*5*12
arr2.reshape(wd);
//遍历
for (int i = 0; i < arr2.shape()[0]; i++)
{
std::cout << i << "页" << std::endl;
for (int j = 0; j < arr2.shape()[1]; j++)
{
for (int k = 0; k < arr2.shape()[2]; k++)
{
std::cout << i << "页" << j << "行" << k << "列" << arr2[i][j][k] << " ";
}
std::cout << std::endl;
}
}
}

环形缓冲区
基本概念
boost库中的 circular_buffer顾名思义是一个循环缓冲器,其 capcity是固定的当容量满了以后,插入一个元素时,会在容器的开头或结尾处删除一个元素。如图所示:

添加元素:push_back()、push_front()、insert()。
删除元素:pop_back()、pop_front()、erase()。
判断容器是否已满:full()。
把缓冲区线性化一个连续的普通数组:linearize()。
来检测是否可以线性化:is_linearize()。
从指定的迭代器位置旋转整个容器:rotate()。
需要注意的是circular_buffer的迭代器不是循环的,指向或超过end()的迭代器也会引发断言异常,前面所说的到达末尾时自动循环使用容器的另一端空间指的是当达到容器的容量上限,继续push_back方法压入元素时,原来begin处的元素就会被覆盖,原来begin + 1处的元素成为新的begin。如果我们需要一种容器在达到容量上限的情况下自动覆盖前面的数据的话就可以使用circular_buffer,整体上来说是一种FIFO的缓存。
circular_buffer的使用代码举例
#include<boost/circular_buffer.hpp>
void BoostTest::test_boost_circular_buffer()
{
//环形缓存(特别像队列)
boost::circular_buffer<int> cb(5);//容量为3
cb.push_back(1);//从尾部插入
cb.push_back(2);
cb.push_back(3);
cb.push_back(4);
cb.push_back(5);//容量已满 1 2 3 4 5
for (int i = 0; i < cb.size(); ++i)
{
cb[i] = cb[i] + 1;//修改缓存内容
std::cout << cb[i] << " "; // 2 3 4 5 6
}
std::cout << std::endl;
//容量已满,尾部插入,踢出头部元素
cb.push_back(7);
for (int i = 0; i < cb.size(); ++i)
{
std::cout << cb[i] << " ";//3 4 5 6 7
}
std::cout << std::endl;
//容量已满,头部插入,踢出尾部元素
cb.push_front(1);
for (int i = 0; i < cb.size(); ++i)
{
std::cout << cb[i] << " ";
}
std::cout << std::endl;//1 3 4 5 6
cb.pop_back();//删除尾部的元素
for (int i = 0; i < cb.size(); ++i)
{
std::cout << cb[i] << " ";
};
std::cout << std::endl;// 1 3 4 5
cb.pop_front();//删除头部的元素
for (int i = 0; i < cb.size(); ++i)
{
std::cout << cb[i] << " ";
}
std::cout << std::endl;//3 4 5
}



347

被折叠的 条评论
为什么被折叠?



