boost 实用工具
1. noncopyable P110
实现一个禁止复制的类
#include <boost/noncopyable.hpp> //or //#include <boost/utility.hpp> class do_not_copy: boost::noncopyable {...};
2. typeof P112
typeof库使用宏模拟了C++0x新增加的typeof和auto关键字,可以减轻书写烦琐的变量类型声明的工作,简化代码。
#include <boost/typeof/typeof.hpp> vector<string> func() { vector<string> v(10); return v; } int main() { BOOST_TYPEOF(2.0*3) x = 2.0*3; BOOST_AUTO(y, 2+3); BOOST_AUTO(&a, new double[20]); //VS2015编译不过 BOOST_AUTO(p, make_pair(1, "string")); BOOST_AUTO(v, func()); return 0; }
向typeof库注册自定义类
#include <boost/typeof/typeof.hpp> #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() namespace ex { struct demo_class {int a,b;}; //一个简单的类 } BOOST_TYPEOF_REGISTER_TYPE(ex::demo_class) //向typeof库注册类 int main() { BOOST_AUTO(x, make_pair("test", ex::demo_class())); cout<<typeid(x).name()<<endl; x.second.a=10; x.second.b = 20; cout<<x.second.a<<x.second.b<<endl; }
3. optional P116
- optional 库使用“容器”语义,包装了“可能产生无效值”的对象,实现了“未初始化”的概念。
就地创建,减少拷贝做代价 这个有使用价值
#include <boost/optional.hpp> #include <boost/utility/in_place_factory.hpp> using namespace boost; int main() { //就地创建string对象,不需要临时对象string("....") optional<string> ops(in_place("test in_place_factory")); cout<< *ops; //就地创建std::vector对象,不需要临时对象vector(10,3) optional<vector<int> > opp(in_place(10,3)); assert(opp-size() == 10 ); assert((*opp)[0] == 3); }
4. assign
为容器初始化或者赋值提供一个方法
operator+=
// 优点: 可应用与stl中定义的标准容器(vector, list, set, map等) // 缺点: 对于其他类型的容器(如boost新容器)则无能为力 void test_assign_plus() { using namespace boost::assign; // 1. vector std::vector<int> values; values += 1, 2, 3, 4, 5, 6, 7, 8, 9; // 插入值到容器的末尾 BOOST_ASSERT(values.size() == 9); BOOST_ASSERT(values[0] == 1); BOOST_ASSERT(values[8] == 9); // 2. set std::set<std::string> s; //标准集合容器 s += "cpp", "java", "c#", "python"; BOOST_ASSERT(s.size() == 4); // 3. map std::map<int, std::string> m; m += std::make_pair(1, "one"), std::make_pair(2, "two"), std::make_pair(3, "three"), std::make_pair(4, "four"); BOOST_ASSERT(m[1] == "one"); BOOST_ASSERT(m[2] == "two"); BOOST_ASSERT(m[3] == "three"); BOOST_ASSERT(m[4] == "four"); }
operator()
// 优点: operator+=使用上有些小的限制,而且在处理map容器也显麻烦,操作符operator()更通用. // 不能直接使用operator(), 而应当使用assign库提供三个辅助函数insert(),push_front(),push_back(). // 这些函数可作用于拥有同名成员函数的容器,接受容器变量作为参数 // 返回一个代理对象list_inserter,它重载了operator(),=等操作符用来实现向容器填入数据的功能。 void test_assign_bracket() { using namespace boost::assign; std::vector<int> v; push_back(v), 1, 2, 3, 4, 5; push_back(v), 6, 7, 8; std::copy(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; std::vector<int> l; push_back(l), 1, 2, 3, 4, 5; push_back(l), 6, 7, 8; std::copy(l.cbegin(), l.cend(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; std::deque<int> d; push_back(d), 1, 2, 3, 4, 5; push_back(d), 6, 7, 8; push_front(d), 0, -1, -2; std::copy(d.cbegin(), d.cend(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; std::map<std::string, int> months; insert(months) ( "january", 31 )( "february", 28 ) ( "march", 31 )( "april", 30 ) ( "may", 31 )( "june", 30 ) ( "july", 31 )( "august", 31 ) ( "september", 30 )( "october", 31 ) ( "november", 30 )( "december", 31 ); BOOST_ASSERT(months.size() == 12); BOOST_ASSERT(months["january"] == 31); }
初始化容器元素的函数: list_of(), map_list_of(), tuple_list_of()
// 操作符+=和()解决了对容器的赋值问题,但有的时候需要在容器构造的时候就完成数据的填充,这种方式较赋值更为高效。 // c++内建的数组和标准字符串类string支持这样做,但stl容器则不行。 // list_of()函数的用法与之前的insert(),push_back()等函数很相似, 也重载了括号, 逗号操作符。 // 它很智能, 返回一个匿名的列表, 可以赋值给任意容器。 void test_assign_list_of() { using namespace boost::assign; const std::list<int> l = list_of(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11); BOOST_ASSERT( l.size() == 11 ); BOOST_ASSERT( l.back() == 11 ); BOOST_ASSERT( l.front() == 1 ); // 二维数组 std::vector<std::vector<int>> v = list_of(list_of(1)(2)) (list_of(3)(4)); v += list_of(5)(6), list_of(7)(8); // 两个类似功能的ref_list_of()和cref_list_of(), // 这两个函数接受变量的引用作为参数来创建初始化匿名列表,较list_of()的效率更高 int a = 1, b = 2, c = 3; std::vector<int> v = ref_list_of<3>(a)(b)(c); assert(v.size() == 3); } void test_assign_map_list_of() { using namespace boost::assign; std::map<int, int> m1 = map_list_of(1, 2)(3, 4)(5, 6)(7, 8)(9, 10); std::map<int, std::string> m2 = map_list_of(1, "one")(2, "two")(3, "three")(4, "four"); }
assign库提供repeat(),repeat_fun()和range()三个函数来减少重复的输入
void test_assign_repeat() { using namespace boost::assign; std::vector<int> v = list_of(1).repeat(3, 2)(3)(4)(5); // 1, 2, 2, 2, 3, 4, 5 std::copy(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; std::deque<int> d; push_front(d).range(v.begin(), v.begin() + 5); // 3, 2, 2, 2, 1 std::copy(d.cbegin(), d.cend(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; }
5. swap P128
boost::swap是对标准库中的std::swap的增强和泛化
int a1[100];
int a2[10];
std::fill_n(a1,10,5);
std::fill_n(a2,10,2);
boost::swap(a1,a2);
特化std::swap P130
特化ADL可找到的swap
6. singleton 单件模式 P131
- singleton_default 泛型单件类
#include <boost/pool/detail/singleton.hpp>
using boost::details::pool::singleton_default; //单件名字空间
class point
{
public:
point(int a=0, int b=0, int c=0):x(a),y(b),z(c)
{cout<<"point ctor"<<endl;}
~point()
{cout<<"point dtor"<<endl;}
//...
};
int main()
{
cout<<"main() start"<<endl;
typedef singleton_default<point> origin; //定义单件
origin::instance().print(); //使用instance()获得单件对象
cout<<"main() finish"<<endl;
}
//例2
class SqlDB_t
{
public:
void connect()
{cout<<"connect db"<<endl;}
void exec(const char* sqlstr)
{ cout<<"exec insert/update/delete:"<<sqlstr<<endl; }
void query(const char* sqlstr)
{cout<<"exec select "<<sqlstr<<endl;}
}
typedef singleton_default<SqlDB_t> SqlDB;
int main()
{
cout << "main() start"<<endl;
SqlDB::instance().connect();
SqlDB::instance().exec("create table goods(int id,varchar name(20)");
SqlDB::instance().exec("insert into goods values(101, 'wii')");
SqlDB::instance().query("select * from goods");
cout<<"main() finish"<<endl;
}
7. boost.serialzation 单件模式 P134
- get_const_instance() 线程安全, get_mutable_instance()非线程安全,会出现竞争问题
有两种使用模式,参见例子
#include <boost/serialization/singleton.hpp> using boost::serialization::singleton; //例1 class point{...}; /////////////////////////// //例2 class point:public singleton<point> //注意这里 {}; //////////////////// int main() { cout<<"main() start"<<endl; typedef singleton<point> origin; //单件类定义 origin::get_const_instance().print(); //常对象 origin::get_mutable_instance().print();//可变对象 cout << "main() finish" <<endl; }
8. tribool –基于三态的布尔逻辑 P136
- optional、tribool的选择方式:如果返回值可能是无效的(不存在有效的返回值),选optional;如果返回值总是确定的,但可能无法确定其意义,那么就是tribool.
9. operators P140
操作符重载的最小实现
- equality_comparable : 要求提供==,可自动实现!=,相等语义
- less_than_comparable : 要求提供<,可自动实现>、<=、>=;
- addable : 要求提供+=,可自动实现+;
- subtractable : 要求提供-=,可自动实现-;
- incrementable : 要求提供前置++,可自动实现后置++;
- decrementable : 要求提供前置–,可自动实现后置–;
equivalent : 要求提供<,可自动实现==,等价语义。
#include <boost/operators.hpp> class point: boost::less_than_comparable<point> //小于关系,私有继承 { public: friend bool operator<(const point& l, const point& r) { retrun (l.x*l.x+l.y*l.y+l.z*l.z < r.x*r.x+r.y*r.y+r.z*r.z); } ... }