Boost源码学习三[实用工具](4)

第四个是assign,

#include <std.hpp>
using namespace std;

#include <boost/assign.hpp>
/*assign:
许多情况下我们都需要为容器初始化或者赋值,填入大量的数据,比如初始错误代码和错误信息,或者是一些测试用的数据。STL容器仅提供了容纳这些数据的方法,但填充的步骤却是相当地麻烦,必须重复调用insert()或者push_back()等成员函数,这正是boost.assign出现的理由.
assign库重载了赋值操作符,operator += , 逗号操作符operator, 和括号操作符operator(), 可以用难以想象的简洁语法非常方便地对STL容器赋值或者初始化,在需要填入大量初值的地方很有用。
#include <boost/assign.hpp>
using namespace boost::assign;
使用操作符 += 向容器增加元素
boost.assign,由于重载了操作符 += 和逗号,可以用简洁到令人震惊的语法完成原来用许多代码才能完成的工作。
使用assign库时必须使用using指示符,只有这样才能让重载的 += ,等操作符在作用域内生效
*/
void case1()
{
    using namespace boost::assign;
    vector<int> v;
    v += 1,2,3,4,5, 6*6;

    for(auto& x : v)
        cout << x << ",";
    cout << endl;

    set<string> s;
    s += "cpp", "java", "c#", "python";

    for(auto& x : s)
        cout << x << ",";
    cout << endl;

    map<int, string> m;
    m += make_pair(0, "空"), make_pair(1, "one"), make_pair(2, "two");
    cout << m[0]<<endl;
    cout << m[1] << endl;
    cout << m[2] << endl;
}
/*
使用操作符()向容器增加元素:
operator+=使用上有些小的限制,而且在处理map容器也显麻烦,
assign库使用操作符operator()提供更通用的解决方案。
不能直接使用operator(), 而应当使用assign库提供三个辅助函数insert(), push_front(), push_back().
这些函数可作用于拥有同名成员函数的容器,接受容器变量作为参数,
返回一个代理对象list_inserter, 它重载了operator(), = 等操作符用来实现向容器填入数据的功能。
*/
#include <forward_list>
void case2()
{
    using namespace boost::assign;
    vector<int> v;
    push_back(v)(1)(2)(3)(4)(5);

    list<string> l;
    push_front(l)("cpp")("java")("c#")("python");

    forward_list<string> fl;
    push_front(l)("matrix")("reload");

    set<double> s;
    insert(s)(3.14)(0.618)(1.732);

    map<int, string> m;
    map <int, string>::iterator t;
    insert(m)(1, "你好")(2, "你好吗")(3, "你真的好吗");
    for (t = m.begin(); t != m.end(); ++t)
    cout << t->first << "," << t->second << endl;
    cout << endl;
}
/*
括号操作符也可以与逗号等操作符配合使用
*/
void case3()
{
    using namespace boost::assign;

    vector<int> v;
    push_back(v),1,2,3,4,5;
    push_back(v)(6),7,64 / 8,(9),10;

    for(auto& x : v)
        cout << x << ",";
    cout << endl;

    deque<string> d;
    push_front(d)() = "cpp","java","c#","python";
    assert(d.size()==5);

    for(auto& x : d)
        cout << x << ",";
    cout << endl;

}

/*
初始化容器元素:
 操作符+=和()解决了对容器的赋值问题,但有的时候需要在容器构造的时候就完成数据的填充,
 这种方式较赋值更为高效。c++内建的数组和标准字符串类string支持这样做,但stl容器则不行。
 assign库使用list_of(),map_list_of()/pair_list_of()和tuple_list_of()三个函数解决了这个问题.
list_of:
  list_of()函数的用法与之前的insert(),push_back()等函数很相似,也重载了括号,逗号操作符。
  它很智能,返回一个匿名的列表,可以赋值给任意容器。
*/
void case4()
{
    using namespace boost::assign;
    vector<int> v = list_of(1)(2)(3)(4)(5);
    // v = [1, 2, 3, 4, 5]
    deque<string> d =
        (list_of("power")("bomb"),"phazon","suit");
    // d = [power bomb phazon suit]
    set<int> s = (list_of(10), 20,30,40,50);
    // s = {10 20 30 40 50}
    map<int, string> m = list_of(make_pair(1, "one"))(make_pair(2, "two"));
    // m = [(1, “one”) (2, “two”)]
    map<int, int> m1 = map_list_of(1, 2)(3, 4)(5, 6);
    //m1 = [(1, 2)(3, 4)(5, 6)]
    map<int, string> m2 = map_list_of(1, "one")(2, "two");
    //m2 = [(1, "one")(2, "two")]

}

/*
减少重复输入:
  assign库提供repeat(),repeat_fun()和range()三个函数来减少重复的输入;
  repeat()函数把第二个参数作为要填入的值,重复第一个参数指定的次数,
  与vector,deque等容器的构造函数很相似,repeat_fun()函数同样重复
  第一个参数的次数,但第二个参数是个无参的函数或函数对象,它返回填
  入的数值;range()函数则可以把一个序列全部或部分元素插入到另一个
  序列里。
  */
#include <cstdlib>                          //for rand()

void case5()
{
    using namespace boost::assign;

    vector<int> v = list_of(1).repeat(3, 2)(3)(4)(5);
    //v = 1,2,2,2,3,4,5
    for(auto& x : v)
        cout << x << ",";
    cout << endl;

    multiset<int> ms ;
    insert(ms).repeat_fun(5, &rand).repeat(2, 1), 10;
    //ms = x,x,x,x,x,1,1,10
    for(auto& x : ms)
        cout << x << ",";
    cout << endl;

    deque<int> d;
    push_front(d).range(v.begin(), v.begin() + 5);
    //d = 3,2,2,2,1
    for(auto& x : d)
        cout << x << ",";
    cout << endl;

}

/*
与非标准容器工作:
 assign库不仅支持全部八个STL标准容器
 (vector,string,deque,list,set,multiset,map,multimao),
 也对STL中的容器适配器提供了适当的支持,包括stack,queue和priority_queue.
  因为stack等容器适配器不符合容器的定义,没有insert,push_back等成员函数,
  所以不能使用赋值的方式填入元素,只能使用初始化的方式,并在list_of表达式
  最后使用to_adapter()成员函数来适配到非标准容器。如果使用逗号操作符还需
  要把整个表达式用括号括起来,才能使用点号调用to_adapter().
  */
#include <stack>
#include <queue>
void case6()
{
    using namespace boost::assign;

    stack<int> stk = (list_of(1), 2, 3).to_adapter();
    stk += 4, 5, 6;
    for(;!stk.empty();)
    {
        cout << stk.top() << " ";
        stk.pop();
    }
    cout << endl;

    queue<string> q = (list_of("china")("us")("uk")).
        repeat(2, "russia").to_adapter();
    push(q)("germany");
    for(;!q.empty();)
    {
        cout << q.front() << " ";
        q.pop();
    }
    cout << endl;

    priority_queue<double> pq = (list_of(1.414), 1.732, 2.236).to_adapter();
    push(pq),3.414,2.71828;
    for(;!pq.empty();)
    {
        cout << pq.top() << " " ;
        pq.pop();
    }

}

/*
引用初始化列表:
在list_of之外assign库还有两个类似功能的ref_list_of()和
cref_list_of(),这两个函数接受变量的引用作为参数来创建初始
化匿名列表,较list_of()的效率更高.
*/
void case7()
{
    using namespace boost::assign;

    int a = 1, b = 2, c = 3;

    vector<int> v = ref_list_of<3>(a)(b)(c);
    assert(v.size() == 3);
}
int main()
{
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值