boost 库实用工具 assign

assign

assign库重载赋值操作符、逗号操作符、括号操作符,用难以想象的简洁语法非常方便的对STL容器赋值或者初始化。

1
2
#include <boost/assign.hpp>
using namespace boost::assign;

1. 使用操作符+=向容器增加元素

在使用assign库时必须使用using指示符,让重载的+=,等操作符在作用域内生效。
+=操作符后可以接若干个可被容器容纳的元素,元素间用逗号分隔。对于map容器,必须用makr_pair()辅助函数生成容器元素。

2. 使用操作符()向容器增加元素

assign库提供三个辅助函数insert()push_front()push_back(),可作用于同名成员函数的容器,接受容器变量作为参数,返回一个代理对象list_inserter,重载operator(),=等操作符实现向容器填入数据的功能。
对于set和map只能使用assign::insert()

3. 初始化容器元素

list_of()函数返回一个匿名的列表,可以赋值给任意容器。
map_list_of()pair_list_of(),map_list_of()可以接受两个参数,自动构造std::pair对象插入map容器,pair_list_of和map_list_of用法功能完全相同。
tuple_list_of()用于初始化元素类型为tuple的容器,tuple是Boost引入的一种新的容器/数据结构。

4. 减少重复输入

repeat()将第二个参数作为要填入的值,重复第一个参数指定的次数。
repeat_fun()将第二个参数作为要填入的值,重复第一个参数指定的次数,但第二个参数是无参的函数或函数对象,返回填入的数量。
range()将一个序列全部或部分元素插入另一个序列里。

5. 与非标准容器工作

assign支持8个STL标准容器(vector、string、deque、list、set、multiset、map、multimap),也对STL中的适配器提供适当支持(stack、queue、priority_queue)。因为stack等容器适配器不符合容器定义,没有insert、push_back等成员函数,不能使用赋值方法填入元素,只能使用初始化的方式,并在list_of表达式最后使用to_adapter()成员函数来适配到非标准容器。如果使用逗号操作符需要把整个表达式用括号括起来,才能使用点号调用to_adapter()。
assign支持部分不在STL中定期的非标准容器,因为它们符合容器的定义,用法和标准容器没什么区别。
assign库从支持大部分Boost库容器,用法与标准容器类似。

6. 高级用法。

list_of()的嵌套使用

list_of()可以就地创建匿名列表,可以嵌套在assign库用法中,创建复杂的数据结构。

引用初始化列表

ref_list_of()和cref_list_of()两个函数接受变量的引用作为参数创建初始化匿名列表。
assign库支持Boost库中的指针容器,提供ptr_push_back()、ptr_list_of()等函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//assign
void TestAssign()
{
using namespace boost::assign;
//向容器中增加元素
vector<int> v;
v += 1, 2, 3, 4, 5, 6, 9*9;
for_each(v.begin(), v.end(), print<int>);

set<string> s;
s += "cpp", "md";
for_each(s.begin(), s.end(), print<string>);

map<int, string> m;
m += make_pair(1, "one"), make_pair(2, "two");
for_each(m.begin(), m.end(), print<pair<int, string>>);

push_back(v)(7)(8)(9);
for_each(v.begin(), v.end(), print<int>);

list<string> l;
push_front(l)("cpp")("java");
for_each(l.begin(), l.end(), print<string>);

set<double> sd;
insert(sd)(1.1)(2.2)(3.3);
for_each(sd.begin(), sd.end(), print<double>);

insert(m)(3, "t")(4, "f");
for_each(m.begin(), m.end(), print<pair<int, string>>);

push_back(v), 1, 2, 3, 4, 5;
push_back(v)(6), 7, 8, (9), 10;
for_each(v.begin(), v.end(), print<int>);


//初始化容器元素
vector<int> vec = list_of(1)(2)(3)(4)(5);
for_each(vec.begin(), vec.end(), print<int>);

deque<string> deq = (list_of("one")("two"), "t", ("f"));
for_each(deq.begin(), deq.end(), print<string>);

map<int, string> mp = (list_of(make_pair(1, "one"))(make_pair(2, "two")), make_pair(3, "t"));
for_each(mp.begin(), mp.end(), print<pair<int, string>>);

map<int, string> mp2 = map_list_of(1, "cpp")(2, "java");
for_each(mp2.begin(), mp2.end(), print<pair<int, string>>);

//减少重复输入
vector<int> v2 = list_of(1).repeat(3, 100).repeat(4, 1000);
for_each(v2.begin(), v2.end(), print<int>);

vector<int> v3;
push_back(v3).range(v.begin(), v.begin()+5);
for_each(v3.begin(), v3.end(), print<int>);

stack<int> stk = (list_of(1), 2, 3).to_adapter();

queue<string> q = (list_of("java")("md")("c")).to_adapter();

vector<vector<int>> vv;
vv += list_of(5)(6), list_of(7)(8);

int a = 1, b = 2, c = 3;
vector<int> v4 = ref_list_of<3>(a)(b)(c);
for_each(v4.begin(), v4.end(), print<int>);

return ;
}