一点一滴成长

导航

boost-容器

1、array

  array相当于是一个增加了STL容器接口的数组,但它不像vector等容器一样可以动态增长,如果需要动态变动array的容量可以使用boost::scoped_array。array适用与对运行速度要求很高的场合。C++11中已支持array。 

#include <algorithm>
using std::sort;

#include "boost/array.hpp"
#include "boost/typeof/typeof.hpp"
using namespace boost;

.......

array<int, 5> ary;
array<int, 5> ary2 = { 1, 2, 3, 4, 5 };//可以使用{}初始化array
ary = ary2;//赋值
swap(ary, ary2)//互换

ary.assign(0);//所有元素赋值为0
ary[0] = 1;//头元素
ary.back() = 10;//尾元素
ary.at(5);//使用at访问元素


int*p = ary.c_array();//获得原始数组指针
int s = ary.size();//获得数组中元素个数
sort(ary.begin(), ary.end());//使用STL排序函数对其排序

for (BOOST_AUTO(pos, ary.begin()); pos != ary.end(); ++pos)//遍历数组,使用BOOST_AUTO需要包含"boost/typeof/typeof.hpp"头文件
{
    int iNum;
    iNum = *pos;
}
View Code

2、unordered_map、unordered_set 

unordered_map和unordered_set都是散列容器(hash container),他们的查询和修改性能都优于map和set。unordered_map中的元素是乱序的,map则默认按照键key从小到大排序存储。

C++11中已支持unordered_map和unordered_set,且其用法与map, set相同。

对于自定义类型的key,map需要在自定义类型中重载< 或者使用函数对象类,如下所示:

//方法1
struct Data
{
    int num;
    bool operator < (Data const& A) const
    {
        return num < A.num;
    }
};

map<Data, int> m;


//方法2
struct Data
{
    int num;
};

class sort
{
public:
    bool operator() (Data const &data1, Data const &data2) const
    {
        return data1.num < data2.num;
    }
};

map<Data, int, sort> m;
View Code

如果unordered_map的key是自定义类型的话,需要添加两个函数对象类,一个用来计算哈希值,一个用来比较值是否相同,如下所示:

#include <unordered_map>
using std::unordered_map;
using std::pair;

#include "boost\functional\hash.hpp"

struct Data
{
    int x;
    int y;
};

struct HashValue
{
    size_t operator()(const Data& p)const
    {
        size_t seed = 0;
        boost::hash_combine(seed, p.x);
        boost::hash_combine(seed, p.y);
        return seed;
    }
};

struct IfEqual
{
    bool operator()(const Data &data1, const Data &data2) const
    {
        return (data1.x == data2.y && data1.y == data2.y);
    }
};

unordered_map<Data, int, HashValue, IfEqual> m;
View Code

boost中的hash类可以计算int、float、string等类型的哈希值,如下所示,hash_combin()函数可以获得两个哈希值的合并值。C++11中也提供了hash类来计算哈希值,不过经我实验,boost与C++11获取相同的一个int值的hash值不同,不知是不是二者使用的hash算法不同导致的还是怎么回事

    #include "boost\functional\hash.hpp"


    size_t hashValue1 = 0, hashValue2 = 0;

    hashValue1 = boost::hash<int>()(28);

    boost::hash<int> HashObj;
    hashValue2 = HashObj(28);
View Code

 3、bimap

  map是单向的(key—>value)关联容器,bimap则可以提供双向映射。bimap有两个视图,左视图和右视图,分别用成员变量left和right访问,相当于两个不同方向的map,其用法与map基本一致。

  由于是双向映射,所以bimap里不仅元素的key不能相同,value也不能相同。

bimap<int, std::string> bmCity;
    typedef bimap<int, std::string>::value_type bimap_value;//map元素类型为pair(使用make_pair()来生成),bimap元素类型为value_type

    bmCity.insert(bimap_value(10, "北京"));
    bmCity.insert(bimap_value(20, "上海"));
    bmCity.insert(bimap_value(30, "广州"));
    bmCity.insert(bimap_value(40, "北京"));

    /*正常作为map使用*/
    bimap<int, std::string>::left_map::const_iterator iter, iter_end;
    iter = bmCity.left.begin();
    iter_end = bmCity.left.end();
    for (; iter != iter_end; iter++)//遍历
    {
        cout << iter->first << "-->" << iter->second << endl;
    }
    iter = bmCity.left.find(20);//通过key索引value
    if (iter != iter_end)
        cout << iter->second << endl;

    /*将value作为key,key为value*/
    bimap<int, std::string>::right_map::const_iterator iter_right, iter_end_right;
    iter_right = bmCity.right.begin();
    iter_end_right = bmCity.right.end();
    for (; iter_right != iter_end_right; iter_right++)//遍历
    {
        cout << iter_right->first << "-->" << iter_right->second << endl;
    }
    iter_right = bmCity.right.find("上海");//通过value索引key
    if (iter_right != iter_end_right)
        cout << iter_right->second << endl;
View Code

4、circular_buffer

  circular_buffer实现了一个循环容器,故其大小是固定的,当达到末尾时自动循环使用容器的另一端空间,如图所示:

  

  添加元素: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,比如用来存储用户最近3天的通话记录。

  circular_buffer_space_optimized是circular_buffer的适配器,circular_buffer是在其定义的时候就分配好了内存,而circular_buffer_space_optimized只有在确实需要时(比如插入元素时)才分配内存,且容器内元素减少时也会自动释放内存。

#include "boost\circular_buffer.hpp"
#include "boost\typeof\typeof.hpp"
using namespace boost;

int main()
{
    circular_buffer<int> cb(5);//定义大小为5的循环容器
    cb.push_back(1);
    cb.push_front(0);

    BOOST_AUTO(pos, cb.begin());//需包含"boost\typeof\typeof.hpp"
    for (; pos != cb.end(); pos++)//遍历循环容器,仅会输出0, 1
        std::cout << *pos << ", " ;
    
    std::cout << *(pos) << std::endl;//迭代器到达end(),继续输出的话会报错!

    return getchar();
}
View Code

5、dynamic_bitset

    dynamic_bitset类似与STL的bitset,但它可以动态改变长度。dynamic_bitset不是容器 ,不支持迭代器和assign库等STL操作。所需头文件:"boost/dynamic_bitset.hpp"。

6、multi_array

   multi_array是多维容器,相当于vector< vector<T> >这种效果,但操作更方便。

 

本文引用和参考出处:《boost程序库完全开发指南》.罗剑锋

posted on 2017-08-24 08:55  整鬼专家  阅读(554)  评论(0编辑  收藏  举报