C++ Boost全库简介

C++ Boost全库简介

本文章大量参考了《Boost程序库完全开发指南》(罗剑锋),如果希望更深入地了解,请参考该书。

本篇只是对Boost库的简单介绍,只是一些浅显的内容,希望各位见谅。

目前进度 40% 左右, 努力填坑中。

由于OSC的Markdown不支持Github Flavored Markdown的“`成块代码形式,代码在这里显示效果非常糟糕。

最新版本请移步 http://192.3.168.141/wordpress/wp-content/uploads/2014/12/boost%E5%BA%93%E5%AD%A6%E4%B9%A0.html

CC-BY-SA
本作品采用知识共享署名-相同方式共享 3.0 未本地化版本许可协议进行许可。

anchor.gif为什么要用boost

  • boost给开发带来了极大的语法简洁
  • boost让C++更像C++
  • boost让程序更加安全

anchor.gif安装

  1. 访问http://www.boost.org/users/download/#live,然后点击current release的download,我一般下载.tar.bz2
  2. 将你下载下来的东西解包,执行./bootstrap.sh
  3. 运行./b2 threading=multi
  4. 运行sudo ./b2 install
  5. 在你的gcc编译选项增加:-Lboost
  6. 接下来试验一小段代码看看是否成功:
#include <boost/date_time/gregorian/gregorian.hpp> using namespace boost::gregorian; using namespace std; int main()
{
 date d1(2014,12,18);
 cout<<d1<<endl;
 return 0;
}

anchor.gif初涉Boost库

如你所见,boost库在使用时要#include在boost目录下的不同头文件,每个文件有着相应的功能。

大多数库#include相应头文件即可使用,然而例如date_time库如果没有-Lboost的话是没法正常运行的。

boost库中内容是在boost:命名空间下的,使用时要注意。

下面我会介绍一些实用的库/类,更多内容需要后续的学习。

    • timer:简易计时
    • progrss_timer:析构时自动输出时间
    • progress_display:控制台进度条
    • date_time:强大的日期时间库
      • gregorian:格里高利历
      • posix_time:精确的计时系统
    • typeof:自动推断类型
    • optional:可选条件下空指针
    • assign:STL批量增加元素
    • swap:高效的交换
    • tribool:拥有不确定值的布尔量
    • operators:自动生成操作符
    • exception:强化的异常类
    • uuid:简单标识符
    • SHA1:重要的摘要算法
    • utility:小功能汇集
      • BOOST_BINARY:简单二进制常量表示
      • BOOST_CURRENT_FUNCTION:返回当前函数声明字符串
    • lexical_cast:字面量转换
    • format:字符串格式化
    • string_algo:字符串专用算法
      • 常用判断函数
      • 比较
      • 修剪空格
      • 查找
      • 替换、删除
      • 分割
      • 合并

anchor.giftimer:简易计时

#include <boost/timer.hpp> #include <iostream>  using namespace boost; using namespace std; int main()
{
    timer a; //声明时计时   double s=0.0;
    for(long long i=0;i< 1LL<<32;i++)
        s+=i*2+i; cout<<a.elapsed()<<endl;
    cout<<s<<endl; 
    return 0;
}

anchor.gifprogrss_timer:析构时自动输出时间

#include <boost/progress.hpp> #include <iostream> using namespace boost; using namespace std; int main()
{
    progress_timer a; double s=0.0;
    for(long long i=0;i< 1LL<<32;i++)
        s+=i*2+i;
    cout<<s<<endl;
    return 0;
}

anchor.gifprogress_display:控制台进度条

#include <boost/progress.hpp> #include <iostream> using namespace boost; using namespace std; int main()
{
    progress_display a(1LL<<32); double s=0.0; for(long long i=0;i< 1LL<<32;i++)
    {
        ++a; //注意!boost库中大多数只实现了前自增,后自增是不行的  s+=i*2+i;
    } cout<<s<<endl;
    return 0;
}

anchor.gifdate_time:强大的日期时间库

anchor.gifgregorian:格里高利历

使用这个库需要引用:

#include <boost/date_time/gregorian/gregorian.hpp> using namespace boost::gregorian;

可以使用多种方式创建date对象:

date t1(2014,12,19);
date t2(2014,Dec,19);
date d3(t2);
date t4=from_string("2014/12/19")

date可以比较大小。

然而,它无法处理1400年之前或9999年之后的日期。

day_clock::local_day返回本地时间

.year.month.day返回日月天

.day_of_week().day_of_year返回当天在一周或一年中的关系

date类型之间不可加,所以有了date_duration这个描述日期间隔的类型:

months m(5);
years y(2);
weeks w(3);

date_duration和自身与date类型均可加

gre_cal::is_leap_year(y)可以简单判断y是否是闰年

anchor.gifposix_time:精确的计时系统

需要引用

#include <boost/date_time/posix_time/posix_time.hpp> using namespace boost::posix_time;

构造时间间隔

time_duration td(1,10,67,230); //时,分,秒,毫秒 前三者会自动进位 time_duration td2=duration_from_string("1:30:27:002");
hours h(1);
minutes m(10);
seconds s(3);
millisec ms(23);

上述对象均可加减

如果要创建一个时间点ptime类型时间点对象,最简单的方法就是:

ptime p(date(2014,12,19),time_duration(21,03,17,002));

记得要包含posix_time和gregorian的两部分头文件和namespace

通过.date()和.time_of_day()来获得当前的日期和时间

microsec_clock::local_time()可以获得微秒精度的本地时间

to_simple_string(t)可以返回一个time_duration或ptime的字符串形式

anchor.giftypeof:自动推断类型

#include <boost/typeof/typeof.hpp> #include <iostream> using namespace std; int main()
{
    BOOST_TYPEOF(3) a=2*6;
    BOOST_AUTO(s,"12312"); cout<<a<<" "<<s<<endl; return 0;
}

默认它只支持内置类,为了支持自己的类:

#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TYPE( 你的类的完全名称 )

anchor.gifoptional:可选条件下空指针

optional模板是一个指针,如果某值满足选定的条件,它就是空指针,否则返回指向该值的指针。

#include <boost/optional.hpp>  #include <iostream>  using namespace std;  using namespace boost;  int main()
{
    int x=-6; int y=3;
    optional<double> d(x>=0,sqrt(x));
    cout<<d.get_value_or(-1)<<endl;  if (!d) cout<<"no result"<<endl;
    optional<double> d2(y>=0,sqrt(y));
    cout<<*d2<<endl;
    return 0;
}

anchor.gifassign:STL批量增加元素

引用:

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

assign重载了+=运算符,可以加入任意多个逗号隔开的元素,然而这些只能用于标准STL:

vector<int> v;
v+= 2,4,2*2+6; set<string> s;
s+="asdsdf","12"; map<int,string> m;
m+=make_pair(123,"123132"),make_pair(1233,"324235");

对于这些STL,有一些更简洁的语法可供使用:

push_back(v)(345)(675);
insert(m)(45,"515")(98,"151sda");

list_of(…)和map_list_of(…)可以返回匿名列表,可被用于任何容器

yourowncont<int> d= (list_of(5)(7)(4),9,10);
yourownmap<int,int> m= map_list_of(6,7)(8,9);

anchor.gifswap:高效的交换

如果有内建函数会调用内建的swap,否则会退化到常见的swap

#include <boost/swap.hpp> using namespace boost;

可以交换数组

int a1[5]={
   0,2,4,3,2};  int a2[5]={
   3,7,2,5,1};
swap(a1,a2);

anchor.giftribool:拥有不确定值的布尔量

引用:

#include <boost/logic/tribool.hpp>  using namespace boost;

tribool类除了有常见的true和false之外,还有一种取值indeterminate(不确定),它的逻辑运算规则请参考原书。但是if (indeterminate)和if (!indeterminate)后的代码都不会执行,可以使用indeterminate(tribool)来判断其是否是不确定。
还可以使用

BOOST_TRIBOOL_THIRD_STATE(unknown)

来把第三态的名字改成unknown

BOOST_TRIBOOL_THIRD_STATE(unknown)  int main()
{
    tribool a(unknown);  if (a) cout<<"true"<<endl;  if (!a) cout<<"false"<<endl;  if (indeterminate(a)) cout<<"indeterminate"<<endl; // 本条才会被执行  return 0;
}

anchor.gifoperators:自动生成操作符

引用:

#include <boost/operators.hpp>  using namespace boost;

这个库提供了只写<运算符就能自动生成>>=<=等功能。

对于一个类,“继承”(实际上并不是真正的继承)
操作符类名1<自身这个类的全称, 操作符类名2<自身这个类的全称> >
就能实现上述方便的功能。

操作符类名见下:

类名 作用
equality_comparable 提供==,生成!=
less_than_comparable 提供<,生成<=>>=
addable 提供+=,生成+
subtractable 提供-=,生成-
multipliable 提供*=,生成*
dividable 提供/=,生成/
incrementable 提供前置++,生成后置++
decrementable 提供前置–,生成后置–
totally_ordered equality_comparable+less_than_comparable
additive addable+subtractable
multiplicative multipliable+dividable
arithmetic additive+multiplicative

另外它还提供了deferenceable解引用自动生成->和indexable生成下标[]操作符的功能,方式不如上所说,请有需要的读者查阅书籍。

class Point:
less_than_comparable<Point>
{ public: int x,y,z;
  explicit Point(int a,int b,int c): x(a),y(b),z(c){};
  void print() const {
   cout<<x<<" "<<y<<" "<<z<<endl;}
  friend bool operator <(const Point& a, const Point& b)
    {
     return (a.x*a.x+a.y*a.y+a.z*a.z<b.x*b.x+b.y*b.y+b.z*b.z);
    }
}; int main()
{
    Point a(3,4,4), b(5,0,0); cout<< (a>=b) <<endl; return 0;
}

这个库相当强大,但应用时也非常复杂,需要仔细使用。

anchor.gifexception:强化的异常类

引用:

#include <boost/exception/all.hpp> using namespace boost;

其精华在于exception类,它可以用<<运算符传入error_info对象的信息,信息可以用get_error_info<…>(…)再取出来,若不存在会返回空指针。

在你定义自己的异常类时,首先虚继承boost::exception,然后为了方便期间typedef一下常见的error_info:

typedef boost::error_info<struct tag_err_no, int>    err_no;

模板前者是一个标记类,仅是为了标记信息类型,没有什么太大的作用,第二个是其中实际存在的信息。

其中已经预定义了一些有用的error_info,详情请翻阅。

对于已经有异常类的场合,可以用enable_error_info(&e)来包装一个异常类型,拥有boost::exception的全部好处。

anchor.gifuuid:简单标识符

uuid是一个16字节的标识符,它在标记一个实体时很有用。

#include <boost/uuid/uuid.hpp>  #include <boost/uuid/uuid_generators.hpp>  #include <boost/uuid/uuid_io.hpp>  #include <iostream>  using namespace std; using namespace boost::uuids;  int main()
{
    uuid u; //它默认是没有构造函数的  cout<<u.size()<<endl; //总是16 vector<unsigned char> v(16,7);
    copy(v.begin(),v.end(),u.begin()); //提供了.begin() 
    iterator cout<<u<<endl; //07070707-0707-0707-0707-070707070707 u.data[15]=8; //可以用data访问里面各位的内容  cout<<u<<endl; //07070707-0707-0707-0707-070707070708 u=nil_generator() (); //先从nil_generator类构造临时对象,再执行  cout<<u.is_nil()<<endl; //1 u=string_generator() ("07070707-0707-cdef-0707-070707070708"); //中间没有-也行  cout<<u<<endl;

    uuid baseuuid = string_generator() ("070707070707cdef0707070707070708");
    u=name_generator(baseuuid) ("bob"); //先要指定一个基uuid,然后以其和名字构造出新的uuid cout<<u<<endl; //9bc6794a-bb5e-547a-9ae6-f295ee8feb4d  cout<<(u<baseuuid)<<endl; //uuid可比较 u=random_generator() (); cout<<u<<endl; //随机uuid  return 0;
}

anchor.gifSHA1:重要的摘要算法

引用

#include <boost/uuid/sha1.hpp>  using namespace boost::uuid::detail;

sha1类提供了

  • .process_byte(abyte)
  • .process_bytes(char*, strlen(char*))
  • .process_block(char*from, char*end)

函数输入数据,然后运行.get_digest(ans)返回unsigned int[5]一个sha值。

anchor.gifutility:小功能汇集

anchor.gifBOOST_BINARY:简单二进制常量表示

#include <boost/utility.hpp> // 或直接 boost/utility/binary.hpp cout<< BOOST_BINARY(1100 100010 0011) <<endl; //每个空格分的段不能超过8个二进制数字 // 同样可以用 BOOST_BINARY_标准整数后缀 来获得不同格式的数字

anchor.gifBOOST_CURRENT_FUNCTION:返回当前函数声明字符串

#include <boost/current_function.hpp>

具体返回取决于编译器。

anchor.giflexical_cast:字面量转换

这个恐怕是cpp中最需要的功能之一了,之前数值转换最快的方法仍是atoi之类,现在终于有了Cpp的实现了。可以轻松在字符串和数值间转换,非常方便。

引用

#include <boost/lexical_cast.hpp>  using namespace boost;

使用

cout<< lexical_cast<string>(6.256) <<endl; cout<< lexical_cast<double>("56.54")<<endl; cout<< lexical_cast<bool>("1") <<endl; //只能转换0 1 ...

实际上,只要

  • 转换起点可流输出
  • 终点可以流输入,并可缺省和拷贝构造

就能利用这个语法转换。

anchor.gifformat:字符串格式化

引用

#include <boost/format.hpp> using namespace boost;

用法

先构造一个format对象,之后其重载了%运算符用来向内传参。

format f("%s:%d+%d=%d\n");
f%"sum"; //参数可以分批传入 cout<< f% 1 % 2 % (1+2) <<endl; //sum:1+2=3 cout<<f.str()<<endl; //指定参数位置也可以... cout<< format("two %1% is %1%%1%") % "sdfsd"<<endl; //two sdfsd is sdfsdsdfsd

语法

  • %05d宽度为5整数,不足补0
  • %-8.3f左对齐,总宽8,小数位3浮点数
  • % 10s10位字符串,不足补
  • %05X宽5大写16进制整数,不足补0

然而,其比printf慢2~5倍,因为其做了很多安全检查。

anchor.gifstring_algo:字符串专用算法

引用、头部分

#include <boost/algorithm/string.hpp>  #include <boost/typeof/typeof.hpp> #include <boost/assign.hpp> #include <iostream> #include <string> using namespace std; using namespace boost; using namespace boost::assign; void printiter(const string::iterator &a,const string::iterator &b)
{ for (BOOST_AUTO(c,a);c!=b;c++) cout<<*c; cout<<endl;
}

anchor.gif常用判断函数

int main()
{ string s("Readme.txt"); //注意:i前缀代表无视大小写  _copy后缀代表复制后返回结果(否则原地处理) cout<<to_upper_copy(s)<<endl; //README.TXT cout<<to_lower_copy(s)<<endl; //readme.txt cout<<istarts_with(s,"read")<<endl; //1 cout<<ends_with(s,"tXt")<<endl; //0 cout<<contains(s,"Me")<<endl; //0 cout<<iequals(s,to_upper_copy(s))<<endl; //1 cout<<ilexicographical_compare(s,"rFad")<<endl; //1 字典序比较前者是否小于后者 cout<<all(s,is_lower()) <<endl; //0 s中每一个元素是否都满足后面的函数 /* 下列函数可以用于all  (实际上,他们并不是真正执行,只是返回了真正的函数对象)
     * is_space
     * is_alnum 是否是字母或数字
     * is_alpha 是否是字母
     * is_cntrl 是否为控制字符
     * is_digit 是否是数字
     * is_lower
     * is_upper
     * is_print
     * is_punct 是否是标点
     * is_xdigit 是否是十六进制数字
     * is_any_of
     * if_from_range
     */

anchor.gif比较

cout<< is_less() ("read","REED") <<endl; //1 cout<< is_not_greater() ("read","REED") <<endl; //1

anchor.gif修剪空格

cout<<trim_copy( string("  abcd   ") )<<endl; //abcd cout<<trim_right_copy( string("  abcd   ") )<<endl; //  abcd

anchor.gif查找

//返回一个range对象,其.begin .end可以像迭代器一样访问 iterator_range<string::iterator> r;
    r=find_first(s,"ea");
    printiter(r.begin(),r.end()); //ea r=ifind_nth(s,"E",1);
    printiter(r.begin(),s.end()); //e.txt r=find_tail(s,6);
    printiter(r.begin(),r.end()); //me.txt //还有find_regex等

anchor.gif替换、删除

//  replace/erase_{first|last|nth|all|head|tail} //  语法同上基本相同,在此不再赘述,replace最后加上一个字符串就行了

anchor.gif分割

list<BOOST_TYPEOF(r)> l;
    split(l,s,is_any_of(".")); for (BOOST_AUTO(c,l.begin());c!=l.end();++c) cout<<*c<<endl; //Readme //txt vector<BOOST_TYPEOF(r)> v;
    find_all(v,s,"."); for (BOOST_AUTO(c,v.begin());c!=v.end();++c) cout<<*c<<endl; //.

anchor.gif合并

vector<string> vs =(list_of("abc")("def")("hij")); cout<<join(vs,"|||")<<endl; //abc|||def|||hij //join_if也可用 }

转载于:https://my.oschina.net/u/1866819/blog/359766

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/109616.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 词向量:如何评价词向量的好坏

    词向量:如何评价词向量的好坏一、前言词向量、词嵌入或者称为词的分布式表示,区别于以往的独热表示,已经成为自然语言任务中的一个重要工具,对于词向量并没有直接的方法可以评价其质量,下面介绍几种间接的方法。二、评价方法对于词向量的评价更多还是应该考虑对实际任务的收益,脱离的实际任务很难确定A模型就一定比B好,毕竟词向量方法更多是一种工具。1、语义相关性任务这个任务用来评价词向量模型在两个词之间的语义相关性,如:…

  • Java 读取文本文件

    Java 读取文本文件FilePathFileReader和FileWriterInputStreamReader和OutputStreamWriterFileInputStream和FileOutputStreamBufferedReaderFileFile代表目录或者文件File类的实例是不可变的;也就是说,一旦创建,由File对象表示的抽象路径名将永远不会改变。下面…

  • 二叉树后序遍历的非递归实现_二叉树的后序遍历非递归详细

    二叉树后序遍历的非递归实现_二叉树的后序遍历非递归详细一、递归实现前序,序,后序遍历;对于二叉树,前面已经采用递归的方式实现的其前序,中序,后序遍历,具体请参见:http://blog.csdn.net/dai_wen/article/details/78955411那么,如何采用非递归的方式遍历树呢?下面,以实现中序遍历二叉树为主题展开:二、非递归实现中序遍历:1,结构:首先,对于中序遍历,我们知道,原则是先走到的结点后访问,后走到的结点

  • 白话经典算法系列之六 高速排序 高速搞定

    白话经典算法系列之六 高速排序 高速搞定

    2021年11月13日
  • php递归算法经典实例_汉诺塔问题递归算法c语言

    php递归算法经典实例_汉诺塔问题递归算法c语言利用PHP实现汉诺塔汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。简而言之,有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号