Boot常用入门库分析

来源:互联网 发布:回到2005年txt下载知轩 编辑:程序博客网 时间:2024/06/16 15:02
<写在前言:最好不要妄图一次性学完,我博客都写了几天,想学那块查看相关标识章节即可>
Boost常用库目录:
1.array库
2.bind库
3.function库
4.ref库
5.smartpointers库
6.regex库                       //这个最有意思了.<自己写个邮箱的匹配规则吧>
7.thread库
8.unordered库
9.tuple库

1.array库

array 在 boost/array.hpp 中定义了一个模板类 boost::array 。 通过使用这个类,可以创建一个跟 C++ 里传统的数组有着相同属性的容器。

  template<typename T, std::size_t N>

  class array{...}

示例代码:

#include<boost/array.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost;

typedef array <int, 5> MyNum;

void main1 ()
{
array <int, 5> barray = { 1, 2, 3, 4, 5 };
barray[0] = 10;
barray.at(4) = 20;
auto *p = barray.data();//存储数组的指针
cout << "第一次输出";
for (int i = 0; i < barray.size();i++)
{
cout << barray[i] << "=="<< p[i] << "  ";
}


cout << endl;
array<int, 5>::iterator ibegin = barray.begin();
array<int, 5>::iterator iend = barray.end();
cout << "第二次输出";
for (array<int, 5>::iterator iTem = ibegin; iTem != iend; iTem++)
{
cout << *iTem<<"  ";
}
cout << endl;
array<string, 3> cmd = { "calc", "notepad", "tasklist" };
cin.get();
}

小结:作为普通c++定长数组的替代品,它提供了数组包含的所有特性,并且提供了与c++标准库容器一致的接口,

在使用上面极具亲和力(迎合了c++开发者的使用习惯),并且由于内部数据结构就是普通数组,因此完全可以用来替代普通数组。


2.bind库

bind 在 boost/bind.hpp中定义了一个模板函数 boost::bind 。通过使用这个函数,可以将多个函数参数绑定到一起,形成一个仿函数对象,并可以选择保存成boost::function对象(该模板类下一节中介绍)。它可用来替换c++标准库中著名的 std::bind1st() 和 std::bind2nd(),简化代码。

它还可以配合其它一些boost库实现特有功能,其中之一就是配合上面提到的boost::function;当两者结合使用时,可以用来实现全局函数和类成员函数回调功能,摆脱以往需要使用虚函数来实现回调接口的麻烦。另外还可以配合boost::asio等库来实现相应功能
绑定两个成员函数的示例代码:
示例代码①:
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
using namespace boost;
//绑定函数的默认值,继承二进制函数类的所有类容
/*
class add:public std::binary_function<int ,int,void>
{
public:
void operator()(int i,int j) const
{
std::cout << i + j << endl;
}
};*/
void   addcopy(int i, int j)
{
std::cout << "i:" << i;
std::cout << "j:" << j << " ";
std::cout << i + j << endl;
}
void   add(int i, int j)
{
std::cout << "i:" << i ;
std::cout << "j:" << j <<" ";
std::cout << i + j << endl;
}
void main()
{
vector<int> myv;
myv.push_back(11);
myv.push_back(23);
myv.push_back(34);
//for_each(myv.begin(), myv.end(), bind1st(add(),10));
for_each(myv.begin(), myv.end(), bind(add, _1, 13));
//bind设置默认参数调用,函数副本机制,不能拷贝构造
bind(addcopy, _1, 13)(15);
cin.get();
}
示例代码②:

#include <boost/bind.hpp>

#include <iostream>

#include <vector>

#include <algorithm>

void add(int i, int j)

{

  std::cout<< i + j << std::endl;

}

int main()

{

std::vector<int> v;

v.push_back(1);

v.push_back(3);

v.push_back(2);

std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1));

}


绑定类成员函数的demo,<文章引用了:http://www.cnblogs.com/yu-chao/p/3979124.html>:个人感觉就是将成员函数变普通函数托管给外部一个意思了.

类的成员函数不同于普通的函数,因为成员函数指针不能直接调用operator(),它必须被绑定到一个对象或指针,然后才能得到this指针进而调用成员函数。因此bind需要 “牺牲”一个占位符,要求提供一个类的实例、引用或者指针,通过对象作为第一个参数来调用成员函数,即:

bind(&X::func,x,_1,_2,…)

这意味着使用成员函数时只能最多绑定8个参数。例如,有一个类demo

struct demo

{

int f(int a,int b){return a+b;}

};

那么,下面的bind表达式都是成立的:

demo a,&ra = a;    //类的实例对象和引用

demo * p = & a;     //指针

cout<<bind(&demo::f,a,_1,20)(10)<<endl;

cout<<bind(&demo::f,ra,_2,_1)(10,20)<<endl;

cout<<bind(&demo::f,p,_1,_2)(10,20)<<endl;


补充外参考资料:

#include <boost/function.hpp>

typedef boost::function<int(int,int)> CMDHANDLER;

CMDHANDLER pfun;
pfun = bind(&demo::f, a, _1, 100);
cout << pfun(200, 100);
//前面示例你可能看的有点懵逼,但到这个示例你应该差不多理解动态相关概念的.括号内真正调用的时候,括号内部在给定参数.来替换前面用占位符代替的值!!!!!!!!!!!!

注意:我们必须在成员函数前面加上取地址的操作符&,表明这是一个成员函数指针,否则会无法编译通过,这是与绑定函数的一个小小的不同。bind同样支持绑定虚拟成员函数,用法与非虚函数相同,虚函数的行为将由实际调用发生时的实例来决定。

小结:bind可被用来生成多元仿函数,功能上可以替换std::bind1st() std::bind2nd(),使得调用形式上更加简洁。对于需要绑定谓词函数,回调等方面的应用,具有很好的使用价值。另外需要注意的是,bind在绑定时会进行值拷贝,因此无法绑定不能拷贝构造的对象。


3.function库

  库 function在 boost/function.hpp 中提供了一个模板类 boost::function。它是一个仿函数类,用于封装各种函数指针,如上一节所述,它通常会与bind结合起来使用。当仿函数对象没有绑定任何函数指针时,调用会抛出boost::bad_function_call异常
示例代码:
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <stdlib.h>
using namespace std;
using namespace boost;

void main()
{
 //  atoi  //char * to  int
boost::function<int(char *)> fun = atoi;
cout << fun("100") + fun("200") << endl;
fun = strlen;
cout << fun("123") + fun("234") << endl;
cin.get();
}

示例代码:与bind进行结合使用

#include <iostream>

#include <stdlib.h>

#include <string.h>

#include <boost/function.hpp>

#include <boost/bind.hpp>

int main()

{

  //函数原形必须是返回值为int,接收参数为const char*的一元函数

  boost::function<int (const char*)> f = atoi;

  std::cout << f("1609") << std::endl;

  //利用bind生成第一个参数固定的仿一元函数

  f = boost::bind(strcmp, "hummada", _1);

  std::cout << f("1609") << std::endl;

  std::cout << f("hummada") << std::endl;

  return0;

}

示例代码:

#include <iostream>

#include <stdlib.h>

#include <string.h>

#include <boost/function.hpp>

#include <boost/bind.hpp>

// 管理者类

class manager

{

public:

  void startWork()

  {

  for(inti = 0;i < 10; ++i)

  {

  if(_cb)

  _cb(i);

  }

  }

  void setProgressCallback(boost::function<void (int)> cb)

  {

  _cb = cb;

  }

private:

  boost::function<void(int)> _cb;

};

// 工作者类

class worker

{

public:

  void doProgress(int pg)

  {

  _pg= pg;

  printf("progress: [%d]\n", pg);

  }

private:

  int _pg;

};

int main()

{

  //回调应用

  manager m;

  worker w;

  m.setProgressCallback(boost::bind(&worker::doProgress, &w, _1));

  m.startWork();

  return0;

}

小结:function和bind配合使用可以很方便的实现类成员回调,极好的应用于一些需要回调的场合。

4.ref
库 ref 在 boost/ref.hpp中提供了模板工厂函数boost::refboost::cref分别对应包装引用和常引用。在上面的小节中分别介绍了bind以及function的使用,而boost::ref可以用来助它们一臂之力。由于bind在绑定参数时,需要进行拷贝,因此当传入的引用对象无法进行拷贝时,编译器就会发生错误。那如何处理这种无法被拷贝的对象引用呢?这个时候ref就派上用场了。当然它的用处也不仅限于此,当在其它应用中,如果拷贝的代价过高时,就可以选择使用它。
示例代码:

#include <iostream>

#include <vector>

#include <algorithm>

#include <boost/bind.hpp>

#include <boost/function.hpp>

void print(std::ostream &os, inti)

{

  os << i << std::endl;

}

int main()

{

  //std::cout为标准输出对象,它是无法进行拷贝的,因此此处必须使用boost::ref来绑定它的引用,

  // 否则会提示拷贝构造失败,因为拷贝构造是私有的

  boost::function<void (int)> pt = boost::bind(print, boost::ref(std::cout), _1);

  std::vector<int> v;

  v.push_back(1);

  v.push_back(2);

  v.push_back(3);

  v.push_back(4);

  std::for_each(v.begin(), v.end(), pt);

  return0;

}

小结:当在某些情况下需要拷贝对象参数时,如果该对象无法进行拷贝,或者拷贝代价过高,这时候就可以选择ref。

5.smartpointers库

智能指针的原理基于一个常见的习语叫做 RAII :资源申请即初始化。 智能指针只是这个习语的其中一例——当然是相当重要的一例。智能指针确保在任何情况下,动态分配的内存都能得到正确释放,从而将开发人员从这项任务中解放了出来。这包括程序因为异常而中断,原本用于释放内存的代码被跳过的场景。 用一个动态分配的对象的地址来初始化智能指针,在析构的时候释放内存,就确保了这一点。因为析构函数总是会被执行的,这样所包含的内存也将总是会被释放。

示例代码:

#include <stdio.h>

#include <stdlib.h>

// 定义一个支持各种指针类型的模板

template <typename T>

class MemHandler

{

public:

  MemHandler():_t(NULL) {}

  MemHandler(T* t):_t(t) {}

  ~MemHandler() {

  if(_t != NULL)

  delete_t;

  }

private:

  T*_t;

};

class Test

{

public:

  Test(){printf("Test construct\n");}

  ~Test(){printf("~Test destroyed\n");}

};

int main()

{

  //程序退出前,会自动释放

  MemHandler<int> handler1(new int);

  MemHandler<Test> handler2(new Test);

  return0;

}

1998年修订的第一版C++标准只提供了一种智能指针:std::auto_ptr。 它基本上就像是个普通的指针: 通过地址来访问一个动态分配的对象。 std::auto_ptr 之所以被看作是智能指针,是因为它会在析构的时候调用 delete 操作符来自动释放所包含的对象。当然这要求在初始化的时候,传给它一个由new 操作符返回的对象的地址。 既然std::auto_ptr的析构函数会调用delete 操作符,它所包含的对象的内存会确保释放掉。 这是智能指针的一个优点。

一.作用域指针

  它独占一个动态分配的对象, 对应的类名为boost::scoped_ptr,定义在boost/scoped_ptr.hpp 中。不像std::auto_ptr,作用域指针不能传递它所包含的对象的所有权到另一个作用域指针。一旦用一个地址来初始化,这个动态分配的对象将在析构阶段释放。因为一个作用域指针只是简单保存和独占一个内存地址,所以boost::scoped_ptr的实现就要比std::auto_ptr简单。 在不需要所有权传递的时候应该优先使用boost::scoped_ptr。 在这些情况下,比起std::auto_ptr它是一个更好的选择,因为可以避免不经意间的所有权传递。因此我们通常可以用它来实现局部动态对象的自动释放,比如在函数调用中产生的动态对象。

示例代码:

#include <boost/scoped_ptr.hpp>

int main()

{

boost::scoped_ptr<int> i(new int);

*i = 1;

*i.get() = 2;

i.reset(new int);

return 0;

}

示例代码:

#include <vector>
#include<algorithm>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include<boost/weak_ptr.hpp>
#include <windows.h>
using namespace std;
void main()
{
boost::scoped_ptr<int> p(new int);//自动释放内存
*p = 12;
cout << *p.get() << endl;
p.reset(new int);
*p.get() = 3;
boost::scoped_ptr<int> pA(nullptr);//独占内存
//pA = p;
cout << *p.get() << endl;
cin.get();
}

二.作用域数组

  作用域数组的使用方式与作用域指针相似。关键不同在于,作用域数组的析构函数使用delete[]操作符来释放所包含的对象。因为该操作符只能用于数组对象,所以作用域数组必须通过动态分配的数组来初始化。对应的作用域数组类名为boost::scoped_array,它的定义在boost/scoped_array.hpp里。

示例代码:

#include <boost/scoped_array.hpp>

int main()

{

boost::scoped_array<int> i(new int[2]);

*i.get() = 1;

i[1] = 2;

i.reset(new int[3]);

}


三.共享指针

  这个智能指针命名为 boost::shared_ptr,定义在boost/shared_ptr.hpp 里。智能指针boost::shared_ptr基本上类似于boost::scoped_ptr关键不同之处在于boost::shared_ptr不一定要独占一个对象。 它可以和其他boost::shared_ptr类型的智能指针共享所有权(内部有计数器相关概念)。在这种情况下,当引用对象的最后一个智能指针销毁后,对象才会被释放。

  因为所有权可以在 boost::shared_ptr之间共享,任何一个共享指针都可以被复制,这跟boost::scoped_ptr是不同的。 这样就可以在标准容器里存储智能指针了——你不能在标准容器中存储std::auto_ptr,因为它们在拷贝的时候传递了所有权。

示例代码:

#include <vector>

#include <algorithm>

#include <boost/shared_ptr.hpp>

void print(boost::shared_ptr<int> i)

{

  printf("%d\n", *i);

}

int main()

{

  std::vector<boost::shared_ptr<int> > v;

  {

  boost::shared_ptr<int> i1(new int(1));

  boost::shared_ptr<int> i2(new int(2));

  v.push_back(i1);

  v.push_back(i2);

  }

 

  std::for_each(v.begin(), v.end(), print);

  return0;

}

示例代码:

#include <stdio.h>

#include <stdlib.h>

#include <boost/shared_ptr.hpp>

class Test {

public:

  Test(inti):_i(i) {printf("Test construct: %d\n", _i);}

  ~Test(){printf("~Test destroyed: %d\n", _i);}

  voidprint() {printf("Test value: %d\n", _i);}

private:

  int _i;

};

int main()

{

  boost::shared_ptr<Test> i1(new Test(1));

  boost::shared_ptr<Test> i2(i1);

  boost::shared_ptr<Test> i3(i1);

  i1.reset(newTest(2));

  i1->print();

  i2->print();

  i3->print();

  return0;

}

示例代码:

void show(boost::shared_ptr<int> p)
{
cout << *p << endl;
}
void  mainK()
{
vector<boost::shared_ptr<int> > v;//装指针的容器
boost::shared_ptr<int> p1(new int(11));
boost::shared_ptr<int> p2(new int(12));
boost::shared_ptr<int> p3(p2);//拷贝
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
for_each(v.begin(), v.end(), show);
cin.get();
}

默认情况下,boost::shared_ptr 使用 delete 操作符来销毁所含的对象。 然而,具体通过什么方法来销毁,是可以指定的,就像下面的例子里所展示的:

示例代码:

#include <boost/shared_ptr.hpp>

#include <windows.h>

int main()

{

  //指定指针对象的释放方式

  boost::shared_ptr<void> h(OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId()), CloseHandle);

  SetPriorityClass(h.get(),HIGH_PRIORITY_CLASS);

  return0;

}

四.共享数组

  共享数组的行为类似于共享指针<并非由共享内存概念加一个类型区别前面独享内存概念>。 关键不同在于共享数组在析构时,默认使用delete[]操作符来释放所含的对象。因为这个操作符只能用于数组对象,共享数组必须通过动态分配的数组的地址来初始化。共享数组对应的类型是boost::shared_array,它的定义在boost/shared_array.hpp 里。

示例代码:

#include <iostream>

#include <boost/shared_array.hpp>

int main()

{

  boost::shared_array<int> i1(new int[2]);

  boost::shared_array<int> i2(i1);

  i1[0]= 1;

  std::cout << i2[0] << std::endl;

  return0;

}

示例代码:

#include <iostream>
#include <vector>
#include<algorithm>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include<boost/weak_ptr.hpp>
#include <windows.h>
using namespace std;




class runclass
{
public:
int  i = 0;
public:
runclass(int num) :i(num)
{
cout << "i create" <<i<< endl;
}
runclass() 
{
cout << "i create" << i << endl;
}
~runclass()
{
cout << "i delete" <<i<< endl;
}
void print()
{
cout << "i =" << i<<endl;
}






};


void testfun()
{


boost::shared_ptr<runclass>  p1(new runclass(10));
boost::shared_ptr<runclass>  p2(p1);
boost::shared_ptr<runclass>  p3(p1);
p1.reset(new runclass(12));
p1->print();
p2->print();
p3->print();
}


void  testfunarray()
{
boost::shared_array<runclass> p1(new runclass[5]);
boost::shared_array<runclass> p2(p1);
}

  弱指针 boost::weak_ptr的定义在boost/weak_ptr.hpp里。到目前为止介绍的各种智能指针都能在不同的场合下独立使用。相反,弱指针只有在配合共享指针一起使用时才有意义。因此弱指针被看做是共享指针的观察者,用来观察共享指针的使用情况。当用到共享指针时,就要考虑是否需要使用弱指针了,这样可以解除一些环形依赖问题。

示例代码;

#include <windows.h>

#include <boost/shared_ptr.hpp>

#include <boost/weak_ptr.hpp>

#include <iostream>

DWORD WINAPI reset(LPVOID p) {

  boost::shared_ptr<int> *sh = static_cast<boost::shared_ptr<int>*>(p);

  sh->reset();

  return0;

}

DWORD WINAPI print(LPVOID p) {

  boost::weak_ptr<int> *w = static_cast<boost::weak_ptr<int>*>(p);

  boost::shared_ptr<int> sh = w->lock();

  if(sh)

  std::cout << *sh << std::endl;

  return0;

}

int main()

{

  boost::shared_ptr<int> sh(new int(99));

  boost::weak_ptr<int> w(sh);

  HANDLEthreads[2];

  threads[0]= CreateThread(0, 0, reset, &sh, 0, 0);

  threads[1]= CreateThread(0, 0, print, &w, 0, 0);

  WaitForMultipleObjects(2, threads, TRUE, INFINITE);

  return0;

}

  boost::weak_ptr必定总是通过boost::shared_ptr来初始化的。一旦初始化之后,它基本上只提供一个有用的方法: lock()。此方法返回的boost::shared_ptr与用来初始化弱指针的共享指针共享所有权。如果这个共享指针不含有任何对象,返回的共享指针也将是空的。当函数需要一个由共享指针所管理的对象,而这个对象的生存期又不依赖于这个函数时,就可以使用弱指针。只要程序中还有一个共享指针掌管着这个对象,函数就可以使用该对象。 如果共享指针复位了,就算函数里能得到一个共享指针,对象也不存在了。

  上例的 main() 函数中,通过Windows API 创建了2个线程。于是乎,该例只能在 Windows 平台上编译运行。第一个线程函数 reset() 的参数是一个共享指针的地址。 第二个线程函数 print() 的参数是一个弱指针的地址。这个弱指针是之前通过共享指针初始化的。一旦程序启动之后,reset()和 print() 就都开始执行了。不过执行顺序是不确定的。 这就导致了一个潜在的问题:reset()线程在销毁对象的时候print() 线程可能正在访问它。通过调用弱指针的 lock() 函数可以解决这个问题:如果对象存在,那么 lock() 函数返回的共享指针指向这个合法的对象。否则,返回的共享指针被设置为0,这等价于标准的null指针。弱指针本身对于对象的生存期没有任何影响。 lock() 返回一个共享指针,print() 函数就可以安全的访问对象了。这就保证了——即使另一个线程要释放对象——由于我们有返回的共享指针,对象依然存在

上面的例子讲的不是很好,推荐博客例讲:http://www.cnblogs.com/TianFang/archive/2008/09/20/1294590.html

小结:对智能指针的良好运用可以有效处理内存、资源等的自我管理释放问题。对于现代c++来说,是必不可少的一件“神器”。同时在boost库里面也有广泛应用,如在asio中,shared_ptr的使用就是其中一例,有兴趣的可以再进行了解。


6.regex库

  BoostC++ 的正则表达式库 Boost.Regex 可以应用正则表达式于 C++ 。正则表达式大大减轻了搜索特定模式字符串的负担,在很多语言中都是强大的功能。

  Boost.Regex 库中两个最重要的类是 boost::regexboost::smatch, 它们都在 boost/regex.hpp文件中定义。 前者用于定义一个正则表达式,而后者可以保存搜索结果。

示例代码:

#include <boost/regex.hpp>

#include <locale>

#include <iostream>

int main()

{

  std::locale::global(std::locale("German"));

  std::strings = "Boris Schaling";

  boost::regexexpr("\\w+\\s\\w+");

  std::cout << boost::regex_match(s, expr) << std::endl;

}

  函数 boost::regex_match()用于字符串与正则表达式的比较。 在整个字符串匹配正则表达式时其返回值为 true 。

示例代码:

#include <boost/regex.hpp>

#include <locale>

#include <iostream>

int main()

{

  std::locale::global(std::locale("German"));

  std::strings = "Boris Schaling";

  boost::regexexpr("(\\w+)\\s(\\w+)");

  boost::smatch what;

  if(boost::regex_search(s, what, expr))

  {

  std::cout << what[0] << std::endl;

  std::cout << what[1] << “-----" << what[2] << std::endl;

  }

}

  函数 boost::regex_search()可以接受一个类型为boost::smatch的引用的参数用于储存结果。 函数boost::regex_search()只用于分类的搜索, 本例实际上返回了两个结果, 它们是基于正则表达式的分组。

示例代码:

#include <boost/regex.hpp>

#include <locale>

#include <iostream>

int main()

{

  std::locale::global(std::locale("German"));

  std::strings = " Boris Schaling ";

  boost::regexexpr("\\s");

  std::stringfmt("_");

  std::cout << boost::regex_replace(s, expr, fmt) << std::endl;

}

  除了待搜索的字符串和正则表达式之外, boost::regex_replace()函数还需要一个格式参数,它决定了子串、匹配正则表达式的分组如何被替换。如果正则表达式不包含任何分组,相关子串将被用给定的格式一个个地被替换。这样上面程序输出的结果为_Boris_Schaling_ 。

示例代码:

#include <boost/regex.hpp>

#include <locale>

#include <iostream>

int main()

{

  std::locale::global(std::locale("German"));

  std::strings = "Boris Schaling";

  boost::regexexpr("(\\w+)\\s(\\w+)");

  std::stringfmt("\\2 \\1");

  std::cout << boost::regex_replace(s, expr, fmt) << std::endl;

}

  格式参数可以访问由正则表达式分组的子串,这个例子正是使用了这项技术,交换了姓、名的位置,于是结果显示为 Schaling Boris 。

示例代码:

#include <boost/regex.hpp>

#include <locale>

#include <iostream>

int main()

{

  std::locale::global(std::locale("German"));

  std::strings = "Boris Schaling";

  boost::regexexpr("(\\w+)\\s(\\w+)");

  std::stringfmt("\\2 \\1");

  std::cout << boost::regex_replace(s, expr, fmt, boost::regex_constants::format_literal) << std::endl;

}

示例代码:

void main()
{
string  str = "chinaen8Glish9abv";
boost::regex expr("(\\w+)\\d(\\w+)");//d代表数字,
boost::smatch what;
if (boost::regex_search(str,what,expr))//按照表达式检索
{
cout << what[0] << endl;
cout << what[1] << endl;

}
else
{
cout << "检索失败";
}
cin.get();
}

示例代码:

void   main()
{
string  str = "chinaen8  Glish9abv";
boost::regex expr("\\d");//d代表数字,
string  kongge = "______";
std::cout << boost::regex_replace(str, expr, kongge) << endl;
cin.get();
}

示例代码:

#include <cstdlib>
#include <stdlib.h>
#include <boost/regex.hpp>
#include <string>
#include <iostream>
using namespace std;
using namespace boost;
regex expression("^select ([a-zA-Z]*) from ([a-zA-Z]*)");
int main(int argc, char* argv[])
{
std::string in;
cmatch what;
cout << "请输入整句话格式为select 内容 form 内容用于测试:";
getline(cin, in);
if (regex_match(in.c_str(), what, expression))
{
for (int i = 0; i<what.size(); i++)
cout << "输入的整句话为:" << what[i].str() << endl;
}
else
{
cout << "Error Input" << endl;
}


getchar();
return 0;
}

个人研究核心自我总结:<自己在搜索下正则表达式构建语法或者下我提供给你的文档链接,都可以.都有介绍>

//非常感谢http://club.topsage.com/thread-2276543-1-1.html提供的参考资料

//1.每个逻辑由项组成.\\d{ 3 }([a - zA - Z] + ).(\\d{ 2 } | N / A)由项:①\\d{ 3 } 本\d[3]转义需要②([a - zA - Z] + )③.能匹配任意一个字符④(\\d{ 2 } | N / A)匹配两个数字或N/A字符
// 2.regex_match为逻辑完全匹配,也就是说,一个待测试的字符串必须能由boost::regex完全解释的通(包括通配),然后就算存在模棱两可也会返回错误的.
//  3.表达式 .* 会吞掉所有东西而后续的子表达式将不能匹配.\\s指一个空格
// 示例:\\d{3}([a-zA-Z]+)(\\d{2}|N/A) 匹配"123Hello12" 不能匹配到 "123Hello12i".而后者可以建立新的规则\\d{3}([a-zA-Z]+)(\\d{2}|N/A).
//  示例\\d{3}([a-zA-Z]+)(\\d{2}|N/A).*能匹配到"123Hello1248465465",因为前面匹配到,后面被销了.所以符合规则.

void main()
{
boost::regex Basi("\\d{3}([a-zA-Z]+)(\\d{2}|N/A).*");
string mystring = "123Hello1248465465";
cout << boost::regex_match(mystring, Basi) << endl;
cin.get();
}



  此程序将 boost::regex_constants::format_literal标志作为第四参数传递给函数boost::regex_replace(),从而抑制了格式参数中对特殊字符的处理。因为整个字符串匹配正则表达式,所以本例中经格式参数替换的到达的输出结果为 \2 \1。

小结:c++的正则表达式库早已有之,但始终没有哪个库纳入到标准化流程中。目前该库已经顺利的成为新一代c++标准库中的一员,结束了c++没有标准正则表达式支持的时代。正则规则开发文档:http://download.csdn.net/detail/qq_24571549/9826584.

7.thread库

  在这个库最重要的一个类就是 boost::thread,它是在 boost/thread.hpp 里定义的,用来创建一个新线程。它已经被纳入c++标准库中。

示例代码:

#include <boost/thread.hpp>

#include <iostream>

void wait(int seconds)

{

  boost::this_thread::sleep(boost::posix_time::seconds(seconds));

}

void thread()

{

  for(inti = 0; i < 5; ++i)

  {

  wait(1);

  std::cout << i << std::endl;

  }

}

int main()

{

  boost::threadt(thread);

  t.join();

}

示例代码:

#include <boost/thread.hpp>

#include <iostream>

void wait(int seconds)

{

  boost::this_thread::sleep(boost::posix_time::seconds(seconds));

}

void thread()

{

  try

  {

  for(inti = 0; i < 5; ++i)

  {

  wait(1);

  std::cout << i << std::endl;

  }

  }

  catch(boost::thread_interrupted&)

  {

  }

}

int main()

{

  boost::threadt(thread);

  wait(3);

  t.interrupt();

  t.join();

}

  小结:新一代c++标准将线程库引入后,将简化多线程开发。

8.unordered库

Boost.Unordered 在 C++标准容器 std::setstd::multisetstd::map std::multimap的基础上多实现了四个容器:boost::unordered_setboost::unordered_multisetboost::unordered_mapboost::unordered_multimap。 那些名字很相似的容器之间并没有什么不同, 甚至还提供了相同的接口。在很多情况下, 替换这两种容器 (std和 boost) 对你的应用不会造成任何影响。

#include <iostream>

#include <string>

#include<boost/unordered_set.hpp>

int main()

{

  typedef boost::unordered_set<std::string> unordered_set;

  unordered_set set;

  set.insert("Boris");

  set.insert("Anton");

  set.insert("Caesar");

  for(unordered_set::iterator it = set.begin(); it != set.end(); ++it)

  std::cout << *it << std::endl;

  std::cout << set.size() << std::endl;

  std::cout << set.max_size() << std::endl;

  std::cout << (set.find("David") != set.end()) << std::endl;

  std::cout << set.count("Boris") << std::endl;

  return0;

}

示例代码:

#include <iostream>
#include<boost/unordered_set.hpp>
#include<string>
using namespace std;
void main()
{
boost::unordered_set<std::string> myhashset;
myhashset.insert("ABC");
myhashset.insert("ABCA");
myhashset.insert("ABCAG");
for (auto ib = myhashset.begin(); ib != myhashset.end();ib++)
{
cout << *ib << endl;
}
std::cout << (myhashset.find("ABCA1") != myhashset.end()) << endl;
cin.get();
}

小结:它里面的库与原有c++标准库中的map、set等相对应,只是内部数据结构改红黑树为hash表来实现,虽然会使得对象的存储空间增大不少,但是查找的平均复杂度却由O(logN))变成O(1),大大提升查找效率。对于需要平凡进行索引查找的应用来说,是极好的选择(当然你还需要考虑效费比,主要是存储空间)。

9.tuple库
tuple 库定义在 boost/tuple/tuple.hpp中,可以用来组合成含有不同数据类型的集合,它类似一个可以随时生成的匿名结构体。它最多可以绑定10个对象。当一个函数需要返回多个值的时候,就可以考虑选择 tuple,通过它可以返回一组数据,这样就无需定义结构体。

示例代码:

#include <iostream>

#include <boost/typeof/typeof.hpp>

#include <boost/tuple/tuple.hpp>

int main()

{

  BOOST_AUTO(t,boost::make_tuple(1, "12345", 'a', 23.534));

  std::cout << t.get<0>() << std::endl;

  std::cout << t.get<1>() << std::endl;

  std::cout << t.get<2>() << std::endl;

  std::cout << t.get<3>() << std::endl;

  return0;

}

示例代码:

#include <string>

#include <iostream>

#include <boost/typeof/typeof.hpp>

#include <boost/tuple/tuple.hpp>

boost::tuple<int, std::string, char, double> return_group()

{

  returnboost::make_tuple(1, "12345", 'a', 23.534);

}

int main()

{

  BOOST_AUTO(t,return_group());

  std::cout << t.get<0>() << std::endl;

  std::cout << t.get<1>() << std::endl;

  std::cout << t.get<2>() << std::endl;

  std::cout << t.get<3>() << std::endl;

  return0;

}


0 0
原创粉丝点击