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_2
pShared_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对象出来
//如果成功提取出来则为真,这个时候就可以安全操作这块内存了
//实例看wkThread
boost::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_ptr
std::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里面的所有元素都调用trace
std::for_each(vcInt.begin(),vcInt.end(),trace);
//综合上述,std::for_each 最后传递一个函数只能是包含了一个int 类型的参数
//如果要将 vcInt 每个元素 都加上 20 则需要std::bind1st
CAdd 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=int
A1 a1, //a1=10 A1=int
A2 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_type
public:
//二.开始构造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,3
s.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依次获取所有函数的返回值,最后返回3
s.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 函数
}//经过作用域 作用域指针释放了内存对象
//我们打印一下信号函数的槽数是多少,此时是0
TRACE("%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());//从首删除第一个i
TRACE("%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 KooBling
string szTrimIf3=boost::algorithm::trim_copy_if(szTrimIf,boost::algorithm::is_any_of("-"));//左右两边去除,Brres KooBling
string szTrimIfDigit="123456789Brres KooBling123456";
string szTrimIfDigit1=boost::algorithm::trim_left_copy_if(szTrimIfDigit,boost::algorithm::is_digit());//左边数字去除,Brres KooBling123456
string szTrimIfDigit2=boost::algorithm::trim_right_copy_if(szTrimIfDigit,boost::algorithm::is_digit());//右边数字去除,123456789Brres KooBling
string 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");//返回true
blStartWith=boost::algorithm::starts_with(szString,"rres");//返回false
//boost::algorithm::iends_with,带i版本忽略大小写
bool blEndWith=boost::algorithm::ends_with(szString,"KooBling");//返回true
blEndWith=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_regex
boost::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_match
boost::regex expr("\\w+\\s\\w+");//正则表达式语法
bool blMatch=boost::regex_match(szString,expr);//返回真
//regex_search
boost::regex expr_search("(\\w+)\\s(\\w+)");
boost::smatch what;
if(boost::regex_search(szString,what,expr_search)){
string szWhat0=what[0];//Brres KooBling
string szWhat1=what[1];//Brres
string szWhat2=what[2];//KooBling
}
//regex_replace
boost::regex expr_replace("\\s");
std::string fmt("-");
string szReg_Replace=boost::regex_replace(szString,expr_replace,fmt);//Brres-KooBling
boost::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 \1
string szReg_Replace22=boost::regex_replace(szString,expr_replace2,fmt2);//KooBling Brres
//boost::tokenizer
std::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_tokens
for (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 format
string 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 +38
string szFormat3=( boost::format("%|1$+| %2% %1%") % 38 % 68).str();//仅仅第一个数字38才加上符号,+38 68 38
try
{
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 68
string szFormat6=( boost::format("%+d %d %d") % 38 % 48 % 68).str();//使用了d,这个比printf还要安全,+38 48 68
string szFormat7=( boost::format("%+s %s %s") % 38 % 48 % 68 ).str();//使用了s,在printf仅仅格式化为字符串,但是这里也可以输出,+38 48 68