noncopyable
概念
- 让一个类从noncopyable继承可以实现禁止对象的复制,使用需要包含头文件"boost/noncopyable.hpp"或"boost/utility.hpp"。
- noncopyable实际上是将类的拷贝构造函数和赋值操作符声明为了private来实现禁止对象的赋值。
optional
概念
- optional类可以表示一个无意义的值,
- 比如以下代码,我们使用get_optional()查找xml上的一个节点,如果该节点不存在的话就会返回一个无效的optional对象,此时对象就是空的。
ptree pt;
read_xml("conf.xml", pt);
boost::optional<int> op = pt.get_optional<int>("conf.gui");
if (op)//节点不存在则op为空
{
int i = op.get();
}
auto x = make_optional(5);
auto y = make_optional<double>((*x > 10),1.0);
成员函数:
-
无参数或参数为boost::none的构造函数用来构造一个无效的对象。
-
如果构造函数中的参数是一个值的引用的话,那么optional中元素其实也是这个值的引用。
-
get()可以获得元素的引用,get_value_or()也可以获得元素的引用,如果对象是无效的话get_value_or()还可以设置一个默认的返回值,get_ptr()可以获得元素的指针。
-
提供了隐式bool类型转换以判断对象的有效性。
-
重载了operator*和operator->,*运算可以获得元素的值,->操作可以获得元素的指针。
-
支持==、!=、>等比较运算。
-
使用make_optional()来创建optional对象的话可以不用指定参数的类型,它可以根据参数来自动推导optional的类型。
BOOST_AUTO(x, boost::make_optional(5));
assert(*x == 5);
in_place()
概念
- optional要求参数具有拷贝语义, 因为它会使用参数值的临时拷贝,
- 如果参数是一个复杂的对象的话这种拷贝方式效率就会很慢,
- 我们可以使用boost库in_place_factory中的in_place()函数来就地创建对象,避免对参数值的临时拷贝,
使用
#include "boost/optional.hpp"
#include "boost/utility/in_place_factory.hpp"
int main()
{
boost::optional<string> ops(boost::in_place("test_in_place"));
//就地创建optional,不需要临时对象string("test_in_place");
return 0;
}
assign
概念
- 使用assign库除了要包含头文件"boost/assign.hpp"外,还要添加对assign命名空间的使用声明:using namespace boost::assign;
- assign库重载了operator+=、operator,、operator(),简化了向STL容器增加元素的方法。
使用
#include "boost/assign.hpp"
using namespace boost::assign;
int main()
{
//使用+=向容器添加元素
vector<int> v;
v += 1, 2, 3, 4 * 4;
map<int, string> m;
m += make_pair(1, "one"), make_pair(2, "two"), make_pair(3, "three");
//使用()向容器添加元素,需要配合assigin的三个函数使用:insert()、push_front()、push_back()
vector<int> v;
push_back(v) (1) (2) (3);
push_back(v), 4, 5, 6;
list<string> l;
push_front(l) ("cpp") ("jave");
push_front(l), "c#", "python";
map<int, string> m;
insert(m) (1, "one") (2, "two") (3, "three");
//assigin使用list_of()、map_list_of()/pair_list_of()、tuple_list_of()来使容器构造的时候就完成了元素的填充,即容器的初始化。
vector<int> v = list_of(1) (2) (3);
map<int, string> m = map_list_of(1, "one") (2, "two") (3, "three");
//tuple_list_of用来初始化元素类型为tuple的容器
return 0;
}
BOOST_AUTO
概念
- BOOST_AUTO的功能类似于auto和any,可以用来定义任意类型数据,且可以在编译时自动推导出表达式的类型。
- BOOST_AUTO属于boost中的typeof库,使用需要包含"boost/typeof/typeof.hpp"。
使用
#include <vector>
#include <boost/typeof/typeof.hpp>
int main()
{
BOOST_AUTO(x, 5); //x为int类型,初始值为5
int n = 10;
BOOST_AUTO(&i, n);//加了&表示引用,所以i为int&类型,初始值为10
BOOST_AUTO(p, new char[20]); //p为char*类型
BOOST_AUTO(v, vector<int>(10, 0)); //v为vector<int>类型,初始为包含10个值为0的元素
BOOST_AUTO(ptr, &n); //ptr为int*类型,指向n
BOOST_AUTO(y, n * 5); //y为int类型,初始值为n * 5
return 0;
}
typeid
概念
- typeid是C++中的运算符关键字,使用它可以获得变量或表达式的类型,它返回的是type_info类型的对象,type_info类的成员函数name()用来获得具体类型的字符串,还支持==、!=判断。
- 如果测试的对象是类类型且至少包含有一个虚函数,则typeid是在运行时获得对象的类型,属于运行时类型识别RTTI。否则,typeid在编译时就可以计算出对象的类型。
使用
int n = 10;
cout << typeid(n).name() << endl;
cout << typeid(&n).name() << endl;
cout << typeid(double).name() << endl;
Base base;
Base * pBase = new Derived;
cout << typeid(base).name() << endl; //输出class Base
cout << typeid(pBase).name() << endl; //输出class Base*
cout << typeid(*pBase).name() << endl; //输出class Derived
表达式推导类型
- 使用BOOST_TYPEOF、typeof、decltype也用来直接定义变量,但变量的数据类型根据指定变量或表达式的数据类型来导出。
BOOST_TYPEOF
说明
- BOOST_TYPEOF属于boost中的typeof库,使用需要包含"boost/typeof/typeof.hpp"。
使用
#include <vector>
#include <boost/typeof/typeof.hpp>
int main()
{
BOOST_TYPEOF(5) x = 10; //x为int类型,初始值为10
int n = 10;
BOOST_TYPEOF(n) y = 0; //y为int类型,初始值为0
BOOST_TYPEOF(&n) p = NULL; //p为int*类型,初始值为NULL
double d = 2.0;
BOOST_TYPEOF(n + d) pi = 3.14; //pi为double类型,初始值为3.14
return 0;
}
typeof
说明
- typeof是GUN C中的关键字。
使用
int n = 999;
typeof(n) var = 666; //var为int类型,初始值为666
int var = 666;
typeof(&var) pVar = NULL; //pVar为int*类型,初始值为NULL
typeof(var * n) value = 0; //value为int类型,初始值为0
decltype
说明
- decltype是c++11中的关键字,如果表达式是左值类型的,则返回的是对应的引用类型。
使用
int main()
{
int n = 666;
decltype(n) var = 0; //var为int类型,初始值为0
int* pVar = NULL;
decltype(pVar) pNum = NULL; //pVar为int*类型,初始值为NULL
int* pV = NULL;
decltype(*pV) Num; //error:*pV是左值类型,所以Num是一个引用,必须初始化
int FuncName();
decltype(FuncName()) value = 666; //value为int类型,初始值为666
decltype(n * 3.0) pi = 3.14; //pi为double类型,初始值为3.14
return 0;
}
result_of
说明
- result_of<>可以获得一个调用表达式的返回类型,调用表达式是一个含有operator()的表达式,它可以是一个函数指针、函数引用、函数对象。
- 可以通过result_of<>的内部类型定义type来获得具体类型,假设类型Func可被调用(具有operator()),func是Func类型的一个左值,那么typeid(boost::result_of<Func(T1, T2, …)>::type) 必然等于typeid(func(t1, t2, …))。
使用
获得函数指针的类型
#include "boost/utility/result_of.hpp"
int main()
{
typedef double(*Func)(double d);
//Func func = sqrt;
boost::result_of<Func(double)>::type x = sqrt(5.0);
return 0;
}
获得函数调用表达式的类型
#include "boost/utility/result_of.hpp"
typedef int(*FuncPtr)(int d);
typename boost::result_of<FuncPtr(int)>::type Func(FuncPtr t, int t1) //这里在result_of<>前必须加typename,否则编译出错
{
return t(t1);
}
int main()
{
typedef int(*FuncPtr)(int d);
FuncPtr func = abs;
Func(func, -5);
return 0;
}
获得泛型函数调用表达式的类型
#include "boost/utility/result_of.hpp"
template<typename T, typename T1>
typename boost::result_of<T(T1)>::type Func(T t, T1 t1) //这里在result_of<>前必须加typename,否则编译出错
{
return t(t1);
}
int main()
{
typedef int(*FuncPtr)(int d);
FuncPtr func = abs;
Func(func, -5);
return 0;
}