boost使用學習總結
阿新 • • 發佈:2018-12-30
boost常用庫案例
http://www.cnblogs.com/wangkangluo1/archive/2011/07/19/2110746.html1.boost::any
boost::any是一種通用的資料型別,可以將各種型別包裝後統一放入容器內,最重要的它是型別安全的。有點象COM裡面的variant。
使用方法:
any::type() 返回包裝的型別
any_cast可用於any到其他型別的轉化
#include <boost/any.hpp>
void test_any() { typedef std::vector<boost::any> many; many a; a.push_back(2); a.push_back(string("test")); for(unsigned int i=0;i<a.size();++i) { cout<<a[i].type().name()<<endl; try { int result = any_cast<int>(a[i]); cout<<result<<endl; } catch(boost::bad_any_cast & ex) { cout<<"cast error:"<<ex.what()<<endl; } } }
2.boost::array
boost::array僅僅是對陣列一層薄薄的封裝,提供跟各種演算法配合的iterator,使用方法很簡單。注意:可以使用{}來初始化array,因為array所有的成員變數都是public的。
#include <boost/array.hpp> void test_array() { array<int,10> ai = {1,2,3}; for(size_t i=0;i<ai.size();++i) { cout<<ai[i]<<endl; } }
3.boost::lexical_cast
lexical_cast用於將字串轉換成各種數字型別(int,float,short etc.)。
#include <boost/lexical_cast.hpp> void test_lexical_cast() { int i = boost::lexical_cast<int>("123"); cout << i << endl; }
4.boost::format
boost::format是用於替代c裡面的sprintf,優點是型別安全,不會因為型別和引數不匹配而導致程式崩潰了,而且還可以重複使用引數。
#include <boost/format.hpp> void test_format() { cout << boost::format("writing %1%, x=%2% : %3%-th try") % "toto" % 40.23 % 50 <<endl; format f("a=%1%,b=%2%,c=%3%,a=%1%"); f % "string" % 2 % 10.0; cout << f.str() << endl; }
5.boost::tokenizer
boost::tokenizer是用於切割字串的,類似於Java裡面的StringTokenizer。
#include <boost/tokenizer.hpp>
void test_tokenizer()
{
string s("This is , a ,test!");
boost::tokenizer<> tok(s);
for(tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg)
{
cout << *beg << " ";
}
}
6.boost::thread
boost::thread是為了提供跨平臺的thread機制。利用boost::function來完成委託。
#include <boost/thread.hpp>
void mythread()
{
cout<<"hello,thread!"<<endl;
}
void test_thread()
{
boost::function< void () > f(mythread);
boost::thread t(f);
t.join();
cout<<"thread is over!"<<endl;
}
7.boost::serialization
boost::serialization提供object的序列化功能。而且提供好幾種序列化的格式,比如text,binary,xml。
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
void test_serialization()
{
boost::archive::text_oarchive to(cout , boost::archive::no_header);
int i = 10;
string s = "This is a test ";
to & i;
to & s;
ofstream f("test.xml");
boost::archive::xml_oarchive xo(f);
xo & BOOST_SERIALIZATION_NVP(i) & BOOST_SERIALIZATION_NVP(s);
boost::archive::text_iarchive ti(cin , boost::archive::no_header);
ti & i & s;
cout <<"i="<< i << endl;
cout <<"s="<< s << endl;
}
8.boost::function
boost::function就是所謂的泛函式,能夠對普通函式指標,成員函式指標,functor進行委託,達到遲呼叫的效果。
#include <boost/function.hpp>
int foo(int x,int y)
{
cout<< "(foo invoking)x = "<<x << " y = "<< y <<endl;
return x+y;
}
struct test
{
int foo(int x,int y)
{
cout<< "(test::foo invoking)x = "<<x << " y = "<< y <<endl;
return x+y;
}
};
void test_function()
{
boost::function<int (int,int)> f;
f = foo;
cout << "f(2,3)="<<f(2,3)<<endl;
test x;
/*f = std::bind1st(std::mem_fun(&test::foo), &x);*/
boost::function<int (test*,int,int)> f2;
f2 = &test::foo;
cout << "f2(5,3)="<<f2(&x,5,3)<<endl;
}
9.boost::shared_ptr
boost::shared_ptr就是智慧指標的實現,不象std::auto_ptr,它是可以stl的容器一起使用的,非常的方便。
#include <boost/shared_ptr.hpp>
class Shared
{
public:
Shared()
{
cout << "ctor() called"<<endl;
}
Shared(const Shared & other)
{
cout << "copy ctor() called"<<endl;
}
~Shared()
{
cout << "dtor() called"<<endl;
}
Shared & operator = (const Shared & other)
{
cout << "operator = called"<<endl;
}
};
void test_shared_ptr()
{
typedef boost::shared_ptr<Shared> SharedSP;
typedef vector<SharedSP> VShared;
VShared v;
v.push_back(SharedSP(new Shared()));
v.push_back(SharedSP(new Shared()));
}
========
boost asio 簡單示例
http://blog.chinaunix.net/uid-1720597-id-85507.html客戶端:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using boost::asio::ip::tcp;
using boost::asio::ip::address;
class session: public boost::enable_shared_from_this<session> {
public:
session(boost::asio::io_service &io_service, tcp::endpoint &endpoint)
: io_service_(io_service), socket_(io_service), endpoint_(endpoint)
{
}
void start() {
socket_.async_connect(endpoint_,
boost::bind(&session::handle_connect,
shared_from_this(),
boost::asio::placeholders::error));
}
private:
void handle_connect(const boost::system::error_code &error) {
if (error) {
if (error.value() != boost::system::errc::operation_canceled) {
std::cerr << boost::system::system_error(error).what() << std::endl;
}
socket_.close();
return;
}
static tcp::no_delay option(true);
socket_.set_option(option);
strcpy(buf, "Hello World!\n");
boost::asio::async_write(socket_,
boost::asio::buffer(buf, strlen(buf)),
boost::bind(&session::handle_write,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_write(const boost::system::error_code& error, size_t bytes_transferred) {
memset(buf, sizeof(buf), 0);
boost::asio::async_read_until(socket_,
sbuf,
"\n",
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
std::cout << buf << std::endl;
}
private:
boost::asio::io_service &io_service_;
tcp::socket socket_;
tcp::endpoint &endpoint_;
char buf[1024];
boost::asio::streambuf sbuf;
};
typedef boost::shared_ptr<session> session_ptr;
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
tcp::endpoint endpoint(address::from_string("192.168.1.1"), 10028);
session_ptr new_session(new session(io_service, endpoint));
new_session->start();
io_service.run();
return 0;
}
伺服器:
#include <string.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using boost::asio::ip::tcp;
using boost::asio::ip::address;
class session: public boost::enable_shared_from_this<session> {
public:
session(boost::asio::io_service &io_service): socket_(io_service)
{
}
void start() {
static tcp::no_delay option(true);
socket_.set_option(option);
boost::asio::async_read_until(socket_,
sbuf_,
"\n",
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
tcp::socket &socket() {
return socket_;
}
private:
void handle_write(const boost::system::error_code& error, size_t bytes_transferred) {
boost::asio::async_read_until(socket_,
sbuf_,
"\n",
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
boost::asio::async_write(socket_,
sbuf_,
boost::bind(&session::handle_write,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp::socket socket_;
boost::asio::streambuf sbuf_;
};
typedef boost::shared_ptr<session> session_ptr;
class server {
public:
server(boost::asio::io_service &io_service, tcp::endpoint &endpoint)
: io_service_(io_service), acceptor_(io_service, endpoint)
{
session_ptr new_session(new session(io_service_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept,
this,
new_session,
boost::asio::placeholders::error));
}
void handle_accept(session_ptr new_session, const boost::system::error_code& error) {
if (error) {
return;
}
new_session->start();
new_session.reset(new session(io_service_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept,
this,
new_session,
boost::asio::placeholders::error));
}
void run() {
io_service_.run();
}
private:
boost::asio::io_service &io_service_;
tcp::acceptor acceptor_;
};
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
tcp::endpoint endpoint(address::from_string("192.168.1.1"), 10028);
server s(io_service, endpoint);
s.run();
return 0;
}
編譯:
g++ -Wall -o client client.cpp -lboost_system
g++ -Wall -o server server.cpp -lboost_system
這裡需要注意的是: async_write, async_read, async_read_until 都是需要達到特定條件才會呼叫回撥函式,
在呼叫回撥函式之前, 不能再次呼叫, 否則接收到的資料很可能是亂的. 所以, 在實際程式碼當中, 會有一個寫緩衝佇列, 當需要write的時, 先放到佇列中, 如果佇列個數為1, 則呼叫async_write, 否則等待函式回撥, 當函式回撥時將首個元素從佇列中移除, 然後接著傳送下一個, 直到佇列為空.
對於client, 由於is_open在async_connect之後就是true狀態了, 因此在async_connect回撥返回之前沒有方法知道是否已經連線成功, 實際程式碼當中一般會增加一個變數以表示該套接字是否已經允許傳送資料.
========
C++之BOOST字串查詢示例
http://www.jb51.net/article/56642.htm這篇文章主要介紹了C++之BOOST字串查詢的方法,例項演示了boost針對字串的查詢、判定及替換等操作,
本文例項講述了C++中BOOST字串查詢的方法,分享給大家供大家參考。具體方法如下:
BOOST 字串查詢示例
複製程式碼 程式碼如下:
#include <string>
#include <iostream>
#include <algorithm>
#include <functional>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/find.hpp>
using namespace std;
using namespace boost;
int main()
{
cout << "* Find Example *" << endl << endl;
string str1("abc___cde___efg");
string str2("abc");
// find "cde" substring
iterator_range<string::iterator> range=find_first( str1, string("cde") );
// convert a substring to upper case
// note that iterator range can be directly passed to the algorithm
to_upper( range );
cout << "str1 with upper-cased part matching cde: " << str1 << endl;
// get a head of the string
iterator_range<string::iterator> head=find_head( str1, 3 );
cout << "head(3) of the str1: " << string( head.begin(), head.end() ) << endl;
// get the tail
head=find_tail( str2, 5 );
cout << "tail(5) of the str2: " << string( head.begin(), head.end() ) << endl;
// char processing
char text[]="hello dolly!";
iterator_range<char*> crange=find_last(text,"ll");
// transform the range ( add 1 )
transform( crange.begin(), crange.end(), crange.begin(), bind2nd( plus<char>(), 1 ) );
// uppercase the range
to_upper( crange );
cout << text << endl;
cout << endl;
return 0;
}
boost 判定函式的使用
複製程式碼 程式碼如下:
#include <string>
#include <iostream>
#include <functional>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/bind.hpp>
using namespace std;
using namespace boost;
int main()
{
cout << "* Predicate Example *" << endl << endl;
string str1("123xxx321");
string str2("abc");
// Check if str1 starts with '123'
cout << "str1 starts with \"123\": " <<
(starts_with( str1, string("123") )?"true":"false") << endl;
// Check if str1 ends with '123'
cout << "str1 ends with \"123\": " <<
(ends_with( str1, string("123") )?"true":"false") << endl;
// Check if str1 containes 'xxx'
cout << "str1 contains \"xxx\": " <<
(contains( str1, string("xxx") )?"true":"false") << endl;
// Check if str2 equals to 'abc'
cout << "str2 equals \"abc\": " <<
(equals( str2, string("abc") )?"true":"false") << endl;
// Classification functors and all predicate
if ( all(";.,", is_punct() ) )
{
cout << "\";.,\" are all punctuation characters" << endl;
}
// Classification predicates can be combined
if ( all("abcxxx", is_any_of("xabc") && !is_space() ) )
{
cout << "true" << endl;
}
cout << endl;
return 0;
}
boost替換示例
複製程式碼 程式碼如下:
#include <string>
#include <iostream>
#include <iterator>
//#include <boost/algorithm/string/replace.hpp>
//#include <boost/algorithm/string/erase.hpp>
//#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string.hpp>
//Following two includes contain second-layer function.
//They are already included by first-layer header
//#include <boost/algorithm/string/replace2.hpp>
//#include <boost/algorithm/string/find2.hpp>
using namespace std;
using namespace boost;
// uppercase formatter
/*
Convert an input to upper case.
Note, that this formatter can be used only on std::string inputs.
*/
inline string upcase_formatter(
const iterator_range<string::const_iterator>& Replace )
{
string Temp(Replace.begin(), Replace.end());
to_upper(Temp);
return Temp;
}
int main()
{
cout << "* Replace Example *" << endl << endl;
string str1("abc___cde___efg");
// Erase 6-9th characters from the string
cout << "str1 without 6th to 9th character:" <<
erase_range_copy( str1, make_iterator_range(str1.begin()+6, str1.begin()+9) ) << endl;
// Replace 6-9th character with '+++'
cout << "str1 with 6th to 9th character replaced with '+++': " <<
replace_range_copy(
str1, make_iterator_range(str1.begin()+6, str1.begin()+9), "+++" ) << endl;
cout << "str1 with 'cde' replaced with 'XYZ': ";
// Replace first 'cde' with 'XYZ'. Modify the input
replace_first_copy( ostream_iterator<char>(cout), str1, "cde", "XYZ" );
cout << endl;
// Replace all '___'
cout << "str1 with all '___' replaced with '---': " <<
replace_all_copy( str1, "___", "---" ) << endl;
// Erase all '___'
cout << "str1 without all '___': " <<
erase_all_copy( str1, "___" ) << endl;
// replace third and 5th occurrence of _ in str1
// note that nth argument is 0-based
replace_nth( str1, "_", 4, "+" );
replace_nth( str1, "_", 2, "+" );
cout << "str1 with third and 5th occurrence of _ replace: " << str1 << endl;
// Custom formatter examples
string str2("abC-xxxx-AbC-xxxx-abc");
// Find string 'abc' ignoring the case and convert it to upper case
cout << "Upcase all 'abc'(s) in the str2: " <<
find_format_all_copy(
str2,
first_finder("abc", is_iequal()),
upcase_formatter );
cout << endl;
return 0;
}
========
boost流的小例子
http://blog.sina.com.cn/s/blog_62b4e3ff0101amtv.html標準流只能處理:標準輸入輸出(stdin,stdout,stderr),檔案,字串。
現在想用流的思想處理一個記憶體塊。將一個記憶體塊當做一個“裝置”
//////////////////////////////////////////////////////////////////////////////////////////////////////
//利用標準庫的stringstream處理
void Chapter1()
{
char data[100];
strcpy(data,"123 456 789"); //要處理的陣列,當做一個記憶體塊
//我們不關心記憶體是從哪裡來的,資料如何賦值上去的。
std::string str(data); //一次拷貝
std::stringstream ss(str);//二次拷貝
//缺點:1)資料多次拷貝。2)只能處理char(0)結束的“字串”,不能處理更廣泛的“字元流”。
int x,y,z;
ss >> x >> y >> z ;
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////利用“小作坊”生產的“家釀”程式碼
#include <streambuf>
#include <istream>
struct my_streambuf : public std::basic_streambuf
{
my_streambuf(char* buffer, std::streamsize length)
{
setg(buffer, buffer, buffer + length);
setp(buffer, buffer + length);
}
};
void Chapter2()
{
char data[100];
strcpy(data,"123 456 789");
my_streambuf buff(data,100); //流緩衝,負責對裝置操作
std::istream iss(&buff); //標準流,負責對使用者資料的格式化,非格式化處理。
int x,y,z;
iss >> x >> y >> z ;
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//利用boost.iostreams庫處理
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <iomanip>
void Chapter3()
{
namespace io = boost::iostreams;
char buff[32]={0};
io::array one(buff,32);
//io::array 的身世
//別名 boost::iostreams::basic_array<char>
//符合 概念<SeekableDevice> 精化於 {概念<Source>,概念<Sink>} 意味著:字元序列的來源,去向。
//具有 模式<Seekable> 意味著:可以隨意移動讀寫頭
//符合 概念<Direct> 意味著:不用檔案快取的那種機制。經過另一個buffer的緩衝是毫無必要的。
io::stream<io::array> s(one);
s << "hello" << ' ' << "world " << std::setw(4) << std::setfill('0') << 123 ; //輸出
io::seek(s,0,std::ios_base::beg); //移動讀寫頭的位置
std::string s1,s2,s3;
s >> s1 >> s2 >> s3; //輸入
s.clear(); //復位標誌位為ios_base::good。因為前面的操作遇到字元char(0),將流狀態變成eof
io::seek(s,0,std::ios_base::beg);
char i;
for (i='a';s; ++i) //迴圈的寫任意多個字元,很快的就能遇到失敗。
//失敗的原因是:陣列不是檔案,只能寫陣列定義時的最大值。
{ //即使是檔案能自動增長,也有物理的最大限制。
s << i ;
if (!s) break;
}
char* pstr = "HELLO WORLD" ;
io::array another(pstr,strlen(pstr)); //定義另一個“陣列”,作為一個新裝置(Device)。
s.close(); //關閉舊Device
if (!s.is_open()){
s.open(another); //開啟另一個Device
}
s >> s1 >> s2; //輸入
//s << 123 //不要嘗試它,pstr指向一個被防寫的記憶體區,任何寫嘗試都會讓程式掛掉。
}
========
boost::filesystem遍歷目錄
http://blog.csdn.net/hhhbbb/article/details/6799564#include <boost::filesystem.hpp>
using namespace boost::filesystem;
void file_executor::iterate_folder(const string full_path)
{
directory_iterator end;
for(directory_iterator pos(full_path);pos !=end; ++pos){
boost::filesystem::path path_(*pos);
if(is_regular(path_)){
string s= path_.string();
vector_files.push_back(s);
files_num ++;
}
else if(is_directory(path_)){
iterate_folder(path_.string());
}
}
}
========