boost使用总结

来源:互联网 发布:阿里巴巴的大数据包括 编辑:程序博客网 时间:2024/06/14 15:21

2.boost::scoped_ptr

{int *p=new int();boost::scoped_ptr<int> i;if(! i){//operator! 调用重载TRACE("空指针");}i.reset(p);//释放原有的内存(此时没有则不释放),重新赋值新的内存地址if(i){//operator bool 调用重载TRACE("实指针");}*i=2;*i.get()=1;int *pNew=new int();i.reset(pNew);//释放原有的内存(p释放了),重新赋值新的内存地址}

    2.1 boost::scoped_ptr与std::auto_ptr 的区别

         1.boost::scoped_ptr 是不可以复制,占有权专一避免更多的内存转移权限造成的问题,std::auto_ptr是可以支持复制的,看下面的代码

          

boost::scoped_array<int> pScoped;boost::scoped_array<int> pScoped2(pScoped);//编译报错boost::scoped_array<int> pScoped3=pScoped;//编译报错
                 
{// 现在,我们有了一个分配好的对象  int* pt1 = new int;  // 将所有权传给了一个auto_ptr对象  auto_ptr<int> pt2(pt1);  // 使用auto_ptr就像我们以前使用简单指针一样,  *pt2 = 12;          // 就像*pt1 = 12  // 用get()来获得指针的值  assert( pt1 == pt2.get() );  auto_ptr<int> pt3(pt2);//这里pt2的所有权会进行转移,拷贝构造auto_ptr<int> pt4=pt3;//这里pt3的所有权会进行转移,拷贝构造auto_ptr<int> pt5;pt5=pt4;//这里pt4的所有权会进行转移,最后pt5获取所有权,赋值操作符}/*_Ty *release() _THROW0(){// return wrapped pointer and give up ownership_Ty *_Tmp = _Myptr;//获取此时的内存地址_Myptr = 0;//内存变量设置为空return (_Tmp);//返回地址}auto_ptr(_Myt& _Right) _THROW0()//拷贝构造: _Myptr(_Right.release())//看到右边的对象会进行release()释放所有权{// construct by assuming pointer from _Right auto_ptr}_Myt& operator=(_Myt& _Right) _THROW0()//赋值操作符{// assign compatible _Right (assume pointer)reset(_Right.release());return (*this);}*/

3.boost::scoped_array

int * p=new int[2];{boost::scoped_array<int> pScoped;if(!pScoped){//operator! 调用重载TRACE("空指针");}pScoped.reset(p);//释放原有的内存(此时没有则不释放),重新赋值新的内存地址if(pScoped){//operator bool 调用重载TRACE("实指针");}pScoped[0]=1;pScoped[1]=2;int *p2=new int[5];pScoped.reset(p2);//释放原有的内存(p内存地址释放完毕),重新赋值新的内存地址}

4.boost::shared_ptr

int * p=new int();{boost::shared_ptr<int> pShared(p);//boost::shared_ptr<int> pShared_2(pShared);//引用同一块内存地址,下面那种用法也可以boost::shared_ptr<int> pShared_2;pShared_2=pShared;//引用同一块内存地址if(! pShared){//operator! 调用重载  TRACE("空指针");  //未调用}if(! pShared_2){//operator! 调用重载  TRACE("空指针");  //未调用}pShared.reset((int*)NULL);//pShared 计数减少,p 内存没有被释放//pShared_2.reset(pShared.get());//pShared_2 计数减少,但是p不会给释放if(pShared){//operator bool 调用重载  TRACE("实指针");  //未调用}  }


//反例int * p=new int();{boost::shared_ptr<int> pShared;boost::shared_ptr<int> pShared_2(p);//开始引用p内存if(! pShared){//operator! 调用重载  TRACE("空指针");  }if(! pShared_2){//operator! 调用重载  TRACE("空指针");  //未调用}pShared.reset(p);//pShared 引用p内存,注:不能两个对象同时引用同一块内存地址,使用 pShared=pShared_2pShared_2.reset((int*)NULL);//pShared_2 计数减少,此时引用计数为0,pShared_2也释放原有的内存(p),由于此时pShared_2释放了p内存地址,在析构的时候pShared又释放了一次导致报错if(pShared){//operator bool 调用重载  TRACE("实指针");  }}

//默认情况下shared_ptr 使用delete来析构,我们也可以指定CloseHandle来析构boost::shared_ptr<void> h(OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId()), CloseHandle); SetPriorityClass(h.get(), HIGH_PRIORITY_CLASS); 

5.boost::weak_ptr

DWORD spThread(IN LPVOID pParam){boost::shared_ptr<int>* pSP=(boost::shared_ptr<int>*)pParam;pSP->reset();//释放所有权return 1;}DWORD wkThread(IN LPVOID pParam){boost::weak_ptr<int>* pWP=(boost::weak_ptr<int>*)pParam;boost::shared_ptr<int> pSPNew=pWP->lock();if(pSPNew){//表示提取了新的一个共享内存出来//spThread 如果比 wkThread 执行快(意思是调用pSP->reset()), 则wkThread不会运行到这TRACE("数据:%d\n",*pSPNew);}return 1;}void CMFC08Dlg::OnBnClickedButton2(){//当共享指针只有一个时候,我们需要在多线程(多环境)操作同一个指针的时候,//在不同环境下,共享指针释放的时刻是不同的,所以我们可以通过waek_ptr的lock函数提取一个share_ptr对象出来//如果成功提取出来则为真,这个时候就可以安全操作这块内存了//实例看wkThreadboost::shared_ptr<int> sp(new int(99));boost::weak_ptr<int> wp(sp);//使用弱指针函数HANDLE thread[2];thread[0]=::CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)spThread,&sp,NULL,NULL);thread[1]=::CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)wkThread,&wp,NULL,NULL);WaitForMultipleObjects(sizeof(thread)/sizeof(HANDLE),thread,TRUE,INFINITE);}

6.boost::intrusive_ptr(侵入式指针调用)

void intrusive_ptr_add_ref(IDispatch *p) { p->AddRef(); } void intrusive_ptr_release(IDispatch *p) { p->Release(); } void check_folder() { CLSID clsid; CLSIDFromProgID(CComBSTR("Scripting.FileSystemObject"), &clsid); void *p; CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, __uuidof(IDispatch), &p); //intrusive_ptr_add_ref 调用,为什么会调用这个函数(),看下面解析boost::intrusive_ptr<IDispatch> disp(static_cast<IDispatch*>(p)); CComDispatchDriver dd(disp.get()); CComVariant arg("C:\\Program Files"); CComVariant ret(false); dd.Invoke1(CComBSTR("FolderExists"), &arg, &ret); TRACE("文件夹存在:%d",ret.boolVal != 0);} //intrusive_ptr_release 调用,看下面解析/*template<class T> class intrusive_ptr{private:    typedef intrusive_ptr this_type;public:    typedef T element_type;    intrusive_ptr() BOOST_NOEXCEPT : px( 0 )    {    }    intrusive_ptr( T * p, bool add_ref = true ): px( p )    {//构造函数会自动调用 intrusive_ptr_add_ref        if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );    }~intrusive_ptr()    {//析构函数会自动调用 intrusive_ptr_release        if( px != 0 ) intrusive_ptr_release( px );    }}*/void CMFC08Dlg::OnBnClickedButton2(){CoInitialize(0); check_folder(); CoUninitialize();}

7.ptr_vector(指针容器,还有boost::ptr_deque, boost::ptr_list, boost::ptr_set, boost::ptr_map, boost::ptr_unordered_set 和 boost::ptr_unordered_map)

//一般情况下我们使用shared_ptrstd::vector< boost::shared_ptr<int> > vc1;vc1.push_back( boost::shared_ptr<int>(new int(1)) );vc1.push_back( boost::shared_ptr<int>(new int(2)) );//但是每次 push_back 都会频繁的调用 增加 或者 减少引用计数//所以boost 也推出了指针容器操作boost::ptr_vector<int> vc2;vc2.push_back(new int(1));vc2.push_back(new int(2));//第二种写法在编写的时候更加简便,但是有一点不同就是ptr_vector是独占指针所有权,类似boost::scoped_ptr//而第一种写法的boost::shared_ptr 是可以共享所有权的

8.Boost.Bind

为什么在std中已有了bind1st还要引入Boost.Bind,那么先看std中代码调用,以及boost的调用如何

void trace(IN int nNum){TRACE("%d\n",nNum);}class CAdd:public std::binary_function<int, int, void> //binary_function 声明了第一个参数是int,第二个参数也是int(这里例子是每个元素传入的值),返回值是void{public:void operator()(int i,int j) const{//i等于10,第一个值TRACE("%d\n",i+j);}protected:private:};void add_boost(int i,int j){TRACE("%d\n",i+j);}void CMFC08Dlg::OnBnClickedButton2(){vector<int> vcInt;vcInt.push_back(1);vcInt.push_back(2);//调用std::foreach 将vcInt里面的所有元素都调用tracestd::for_each(vcInt.begin(),vcInt.end(),trace);//综合上述,std::for_each 最后传递一个函数只能是包含了一个int 类型的参数//如果要将 vcInt 每个元素 都加上 20 则需要std::bind1stCAdd addX;std::for_each(vcInt.begin(),vcInt.end(),std::bind1st(addX,10));//binder1st<CAdd>//解析一下 for_each 调用流程 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)//_Func=std::binder1st(addX,20) 构造了一个对象//遍历每一个元素的时候,会调用//_Func(*_First);展开就是下面的调用// binder1st(*_First) 再展开就是,注意这里是binder1st 不是 bind1st函数,binder1st是一个模板类// CAdd::operator()(20,*_First)//boost::bind的调用std::for_each(vcInt.begin(),vcInt.end(),boost::bind(add_boost,10,_1));}
深入boost::bind的分析

//BOOST_BIND_ST 函数的调用类型template<class R, class B1, class B2, class A1, class A2> //模板定义    _bi::bind_t< R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2), typename _bi::list_av_2<A1, A2>::type > //返回类型    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2), //add_boost R=void,B1=int,B2=intA1 a1, //a1=10 A1=intA2 a2 //a2=_1){    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2);    typedef typename _bi::list_av_2<A1, A2>::type list_type;//一.构造对象(_bi::bind_t),R是返回值(void),F是调用函数,list_type保存了调用参数的列表类型//a1=10,a2等于_1    return _bi::bind_t<R, F, list_type> (f, list_type(a1, a2));//五.返回 _bi::bind_t 对象,保存了add_boost,以及 list_type(a1, a2) 的参数列表}template<class T> class _bi::value{public:    value(T const & t): t_(t) {}    T & get() { return t_; }    T const & get() const { return t_; }    bool operator==(value const & rhs) const    {        return t_ == rhs.t_;    }private:    T t_;};template<class T> struct add_value{    typedef _bi::value<T> type;};template<class A1, class A2> struct list_av_2{    typedef typename add_value<A1>::type B1;//_bi::value<A1> B1    typedef typename add_value<A2>::type B2;//_bi::value<A2> B2    typedef list2<B1, B2> type;//list2<_bi::value<A1>,_bi::value<A2>> type};template<class A1> struct storage1{//四.构造 storage1    explicit storage1( A1 a1 ): a1_( a1 ) {}    template<class V> void accept(V & v) const    {        BOOST_BIND_VISIT_EACH(v, a1_, 0);    }    A1 a1_;};template< class A1 > class list1: private storage1< A1 >{private:    typedef storage1< A1 > base_type;public:    explicit list1( A1 a1 ): base_type( a1 ) {}//八.取出[构造一个list1 传入调用] 传入的值    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }//九.取出10这个值template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }}template<class A1, class A2> struct storage2: public storage1<A1>{    typedef storage1<A1> inherited;//三.构造storage2对象,由于从storage1<A1>,所以需要构造storage1<A1>    storage2( A1 a1, A2 a2 ): storage1<A1>( a1 ), a2_( a2 ) {}    template<class V> void accept(V & v) const    {        inherited::accept(v);        BOOST_BIND_VISIT_EACH(v, a2_, 0);    }    A2 a2_;};template< class A1, class A2 > class list2: private storage2< A1, A2 >{private:    typedef storage2< A1, A2 > base_type;//注意 storage2< A1, A2 > 重新定义为 base_typepublic://二.开始构造list2,由于从storage2< A1, A2 > 继承    list2( A1 a1, A2 a2 ): base_type( a1, a2 ) {}    template<class F, class A> void operator()(type<void>, F & f, A & a, int)    {//七.最后add_boost调用由 unwrapper<F>::unwrap(f, 0) 返回函数地址,//a 指向lis1,这里取值,根据[] 传入的参数类型进行取值//a1_ 是 storage1 的成员,list2继承了storage2//a2_ 是 storage2 的成员,list2继承了storage2        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);    }}template<class R, class F, class L> class bind_t{private:    F f_;//add_boost 的函数地址    L l_;//list_type(a1, a2) 对象public:    typedef typename result_traits<R, F>::type result_type;    typedef bind_t this_type;    bind_t( F f, L const & l ): f_( f ), l_( l ) {}    template<class A1> result_type operator()( A1 && a1 )    {//六.循环遍历,a1此时是列表参数        list1< typename list_add_cref<A1>::type > a( a1 );//构造一个list1 传入调用        return l_( type<result_type>(), f_, a, 0 );    }}

9.boost::signal(信号触发器,可以触发多个信号)
int trace(IN int nNum){TRACE("trace %d\n",nNum);return 1;}int trace2(IN int nNum){TRACE("trace2 %d\n",nNum);return 2;}int trace3(IN int nNum){TRACE("trace3 %d\n",nNum);return 3;}template <typename T>struct singalResult{typedef T result_type;template <typename InputIterator>T operator()(InputIterator first,InputIterator last) const{return T(first,last);}};void CMFC08Dlg::OnBnClickedButton2(){boost::signal<int (int ),singalResult< vector<int> > > s;s.connect(trace);//信号槽连接s.connect(trace2);//信号槽连接s.connect(trace3);bool blRet=s.empty();std::vector<int> v=s(55);//v依次获取所有函数的返回值,1,2,3s.disconnect_all_slots();int nums=s.num_slots();blRet=s.empty();}

void CMFC08Dlg::OnBnClickedButton2(){boost::signal<int (int )> s;//采用默认的写法s.connect(trace);//信号槽连接s.connect(trace2);//信号槽连接s.connect(trace3);bool blRet=s.empty();std::vector<int> v=s(55);//v依次获取所有函数的返回值,最后返回3s.disconnect_all_slots();int nums=s.num_slots();blRet=s.empty();}

int trace(IN int nNum){TRACE("trace %d\n",nNum);return 1;}int trace2(IN int nNum){TRACE("trace2 %d\n",nNum);return 2;}int trace3(IN int nNum){TRACE("trace3 %d\n",nNum);return 3;}template <typename T>struct singalResult{typedef T result_type;template <typename InputIterator>T operator()(InputIterator first,InputIterator last) const{return *std::min_element(first,last);//重新取结果值}};void CMFC08Dlg::OnBnClickedButton2(){boost::signal<int (int ),singalResult< vector<int> > > s;s.connect(trace);//信号槽连接s.connect(trace2);//信号槽连接s.connect(trace3);bool blRet=s.empty();int v=s(55);//v依次获取所有函数的返回值s.disconnect_all_slots();int nums=s.num_slots();blRet=s.empty();}

class CHello{public:void test_hello(){TRACE("Hello\n");}protected:private:};void CMFC08Dlg::OnBnClickedButton2(){boost::signal<void ()> s;{boost::scoped_ptr<CHello> pScoped(new CHello);//作用域指针s.connect(boost::bind(&CHello::test_hello,pScoped.get()));//根据指针对象绑定test_hello 函数}//经过作用域 作用域指针释放了内存对象//我们打印一下信号函数的槽数是多少TRACE("%d\n",s.num_slots());if(s.num_slots()){s();//内存已经释放了,再次调用会引发其他问题}}

class CHello:public boost::signals::trackable //继承这个对象,如果作用域释放了对象也随着释放了信号关联{public:void test_hello(){TRACE("Hello\n");}protected:private:};void CMFC08Dlg::OnBnClickedButton2(){boost::signal<void ()> s;{boost::scoped_ptr<CHello> pScoped(new CHello);//作用域指针s.connect(boost::bind(&CHello::test_hello,pScoped.get()));//根据指针对象绑定test_hello 函数}//经过作用域 作用域指针释放了内存对象//我们打印一下信号函数的槽数是多少,此时是0TRACE("%d\n",s.num_slots());if(s.num_slots()){s();//由于CHello继承了 boost::signals::trackable 对象所以这里不会调用}}

10.boost::algorithm::erase_XX

std::locale::global(std::locale("chs")); std::string s = "Bois Schoolist"; TRACE("%s\n",boost::algorithm::erase_first_copy(s,"i").c_str());//从首删除第一个iTRACE("%s\n",boost::algorithm::erase_nth_copy(s,"i",0).c_str());//第0个位置开始删除TRACE("%s\n",boost::algorithm::erase_last_copy(s,"i").c_str());//从末尾位置开始删除TRACE("%s\n",boost::algorithm::erase_all_copy(s,"i").c_str());//删除所有i的字符TRACE("%s\n",boost::algorithm::erase_head_copy(s,5).c_str());//从首删除5个TRACE("%s\n",boost::algorithm::erase_tail_copy(s,8).c_str());//从尾删除8个

11.boost::algorithm::join
vector<string> vcStr;vcStr.push_back("Hello");vcStr.push_back("world");string sz=boost::algorithm::join(vcStr," ");

12.boost字符串操作大全

vector<string> vcStr;vcStr.push_back("Hello");vcStr.push_back("world");string sz=boost::algorithm::join(vcStr," ");//replace函数string szReplace="Brres KooBling";//boost::algorithm::ireplace_first_copy,带i版本忽略大小写string szResult1=boost::algorithm::replace_first_copy(szReplace,"B","D");//从首部开始将第一个B替换成D,Drres KooBling//boost::algorithm::ireplace_nth_copy,带i版本忽略大小写string szResult2=boost::algorithm::replace_nth_copy(szReplace,"B",0,"d");//从第0个字符串开始将B替换成d,drres KooBling//boost::algorithm::ireplace_last_copy,带i版本忽略大小写string szResult3=boost::algorithm::replace_last_copy(szReplace,"B","D");//从尾部开始将B替换成D,Brres KooDling//boost::algorithm::ireplace_all_copy,带i版本忽略大小写string szResult4=boost::algorithm::replace_all_copy(szReplace,"B","D");//全部B字符替换成D,Drres KooDling//boost::algorithm::ireplace_head_copy,带i版本忽略大小写string szResult5=boost::algorithm::replace_head_copy(szReplace,2,"Herio");//将前面两个字符都替换成Herio,Heriores KooBling//boost::algorithm::ireplace_tail_copy,带i版本忽略大小写string szResult6=boost::algorithm::replace_tail_copy(szReplace,3,"ooo");//将末尾3个字符串都替换成ooo,KooBlooo//trim函数string szTrim="   Brres KooBling   ";string szTrim1=boost::algorithm::trim_left_copy(szTrim);//左边空格去除string szTrim2=boost::algorithm::trim_right_copy(szTrim);//右边空格去除string szTrim3=boost::algorithm::trim_copy(szTrim);//左右两边空格去除string szTrimIf="--Brres KooBling--";string szTrimIf1=boost::algorithm::trim_left_copy_if(szTrimIf,boost::algorithm::is_any_of("-"));//左边-去除,Brres KooBling--string szTrimIf2=boost::algorithm::trim_right_copy_if(szTrimIf,boost::algorithm::is_any_of("-"));//右边-去除,--Brres KooBlingstring szTrimIf3=boost::algorithm::trim_copy_if(szTrimIf,boost::algorithm::is_any_of("-"));//左右两边去除,Brres KooBlingstring szTrimIfDigit="123456789Brres KooBling123456";string szTrimIfDigit1=boost::algorithm::trim_left_copy_if(szTrimIfDigit,boost::algorithm::is_digit());//左边数字去除,Brres KooBling123456string szTrimIfDigit2=boost::algorithm::trim_right_copy_if(szTrimIfDigit,boost::algorithm::is_digit());//右边数字去除,123456789Brres KooBlingstring szTrimIfDigit3=boost::algorithm::trim_copy_if(szTrimIfDigit,boost::algorithm::is_digit());//左右两边数字去除,Brres KooBling//boost::algorithm::is_upper(),boost::algorithm::is_lower()  大写小写判断string szString="Brres KooBling";//boost::algorithm::istarts_with,带i版本忽略大小写bool blStartWith=boost::algorithm::starts_with(szString,"Brres");//返回trueblStartWith=boost::algorithm::starts_with(szString,"rres");//返回false//boost::algorithm::iends_with,带i版本忽略大小写bool blEndWith=boost::algorithm::ends_with(szString,"KooBling");//返回trueblEndWith=boost::algorithm::ends_with(szString,"KooBlin");//返回false//boost::algorithm::icontains,带i版本忽略大小写bool blContain=boost::algorithm::contains(szString,"es");//返回true//boost::algorithm::ilexicographical_compare,带i版本忽略大小写bool blCompare=boost::algorithm::lexicographical_compare(szString,"Brres KooBling");//按字典比较两个字符串,返回false//split,字符串切割vector<string> vcSplit;boost::algorithm::split(vcSplit,szString,boost::algorithm::is_space());//vcSplit 包含了Brres,KooBling//find_regex,Boost::StringAlgorithm 很多函数都支持正则表达式,boost::algorithm::replace_regex,boost::algorithm::erase_regex,boost::algorithm::split_regexboost::iterator_range<std::string::iterator> itFindRegex=boost::algorithm::find_regex(szString,boost::regex("\\w\\s\\w"));string szFindRegex(itFindRegex.begin(),itFindRegex.end());//s K//regex_matchboost::regex expr("\\w+\\s\\w+");//正则表达式语法bool blMatch=boost::regex_match(szString,expr);//返回真//regex_searchboost::regex expr_search("(\\w+)\\s(\\w+)");boost::smatch what;if(boost::regex_search(szString,what,expr_search)){string szWhat0=what[0];//Brres KooBlingstring szWhat1=what[1];//Brresstring szWhat2=what[2];//KooBling}//regex_replaceboost::regex expr_replace("\\s");std::string fmt("-");string szReg_Replace=boost::regex_replace(szString,expr_replace,fmt);//Brres-KooBlingboost::regex expr_replace2("(\\w+)\\s(\\w+)");std::string fmt2("\\2 \\1");//boost::regex_constants::format_literal 抑制了\2 和 \1 的原本作用,这个原来的作用\1 是表示正则组1的内容,\2 表示正则组2的内容string szReg_Replace2=boost::regex_replace(szString,expr_replace2,fmt2,boost::regex_constants::format_literal);//\2 \1string szReg_Replace22=boost::regex_replace(szString,expr_replace2,fmt2);//KooBling Brres//boost::tokenizerstd::string szTokenizer = "Boost C++ libraries";vector<string> vcToken;boost::tokenizer< boost::char_separator<char> > tok(szTokenizer);for (boost::tokenizer<boost::char_separator<char>>::iterator it=tok.begin();it!=tok.end();it++){vcToken.push_back(*it);//Boost,C,+,+,libraries,因为 boost::char_separator 类默认将空格和标点符号视为分隔符}vcToken.clear();boost::tokenizer< boost::char_separator<char> > tok2(szTokenizer,boost::char_separator<char>(" "));for (boost::tokenizer< boost::char_separator<char>>::iterator it=tok2.begin();it!=tok2.end();it++){vcToken.push_back(*it);//Boost,C++,libraries,因为boost::char_separator<char> 指定了使用空格分隔}vcToken.clear();boost::tokenizer< boost::char_separator<char> > tok3(szTokenizer,boost::char_separator<char>(" ","+"));//同时指定空格,+for (boost::tokenizer< boost::char_separator<char>>::iterator it=tok3.begin();it!=tok3.end();it++){vcToken.push_back(*it);//Boost,C,+,+,libraries}vcToken.clear();boost::tokenizer< boost::char_separator<char> > tok4(szTokenizer,boost::char_separator<char>(" ","+",boost::keep_empty_tokens));//同时指定空格,+,并且设置保持keep_empty_tokensfor (boost::tokenizer< boost::char_separator<char>>::iterator it=tok4.begin();it!=tok4.end();it++){//如果连续找到两个分隔符,他们之间的部分表达式将为空vcToken.push_back(*it);//Boost,C,+,空格,+,空格,libraries}vcToken.clear();string szEscaped_list("Boost,\"C++ libraries\",1,2");boost::tokenizer< boost::escaped_list_separator<char> > tok5(szEscaped_list);for (boost::tokenizer< boost::escaped_list_separator<char>>::iterator it=tok5.begin();it!=tok5.end();it++){//以逗号为分隔,如果两个字符串有空格以引号引起来vcToken.push_back(*it);//Boost,C++ libraries,1,2}//boost formatstring szFormat1=( boost::format("%1%.%2%") % 6 % "第二个参数" ).str();//%1% 表示取第一个参数的值 6.第二个参数string szFormat2=( boost::format("%1% %2% %1%") % boost::io::group(std::showpos,38) % 68).str();//std::showpos() 通过 boost::io::group() 与数字 38 连接 +68 68 +38string szFormat3=( boost::format("%|1$+| %2% %1%") % 38 % 68).str();//仅仅第一个数字38才加上符号,+38 68 38try{string szFormat4=( boost::format("%|+| %2% %1%")  % 48 % 68).str();//这行代码有问题,所以会抛出一个异常,%|+|这里使用了非引用数据类型,%2% 这里使用了引用数据类型,不能交叉使用}catch (std::exception& e){TRACE("%s",e.what());//在这里输出一个异常}string szFormat5=( boost::format("%|+| %|| %||") % 38 % 48 % 68).str();//统一使用了非引用数据类型,+38 48 68string szFormat6=( boost::format("%+d %d %d") % 38 % 48 % 68).str();//使用了d,这个比printf还要安全,+38 48 68string szFormat7=( boost::format("%+s %s %s") % 38 % 48 % 68 ).str();//使用了s,在printf仅仅格式化为字符串,但是这里也可以输出,+38 48 68