Boost - 数据类型
-
auto
-
decltype
-
any
-
tuple
-
variant
auto:
auto是C++11中的关键字,它可以通过类型推导自动得到变量或对象的类型,需要注意的是auto会忽略引用,因为引用其实就代表原对象:
用法1:
auto x = 1;
用法2:
for(auto &x : arr)
decltype:
如果我们希望从表达式中推断出要定义变量的类型,但却不想用表达式的值去初始化变量,那么可以使用decltype,需要注意的是如果decltype使用的变量加上一个括号的话那么decltype会返回对应的引用类型:
用法:
int func(int i)
{
return i;
}
decltype(func(0)) num = 100; //num是int类型,不会调用func()
int i = 100;
decltype((i)) d = num; //d是int引用类型,其指向num
any:
any功能与auto类似,二者不同之处在于:
-
auto是一个类似int、double、string的C++关键字,它不是一个类,所以没有成员函数可调用,直接把他当做int、double、string这种关键字来使用。
-
any是一个类,只能通过any_cast<>获得any的实际内部值,而不能像auto定义的对象那样直接使用它。
-
any也可以用来存储任意类型元素,如int、double、string、vector或自定义类型。它能够存储任意类型的原因是其构造函数和赋值函数opeartor=是模板函数,可以接收任意类型。
-
any不是一个模板类,所以定义元素的时候不必使用<>,如any a = 10;
需要注意的有两点:
- 在any存储字符串的时候只能使用string,如any a = string(“hello”);,不能使用C风格的字符串,如:any a = “hello”;
- 如果保存动态内存指针类型,会引起内存泄露,解决方法是使用智能指针shared_ptr来指向动态内存,如:shared_ptr ptrSmart(new char[10]); any a = ptrSmart;
any的出现让C++仿佛变成了一种弱类型的动态语言。
使用:
- any::empty()判断any是否为空
- any::type()获得内部对象的类型,是一个标准type_info类的引用
- any_cast<>()获得any内部对象值或内部对象指针或内部对象的引用
用法:
#include <vector>
#include "boost/any.hpp"
#include "boost/assign.hpp"
using namespace boost::assign;
template <typename T>
bool match_type(boost::any& a)
{
if (a.empty())
return false;
return typeid(T) == a.type();
}
template<typename T>
T get_value(boost::any& a)
{
BOOST_ASSERT(match_type<T>(a));
return boost::any_cast<T>(a);
}
template <typename T>
T* get_pointer(boost::any& a)
{
BOOST_ASSERT(match_type<T>(a));
return boost::any_cast<T>(&a);
}
template <typename T>
T& get_reference(boost::any& a)
{
BOOST_ASSERT(match_type<T>(a));
return boost::any_cast<T&>(a);
}
int main()
{
boost::any a = 10;
int iNum = get_value<int>(a);//获得a的内部元素
cout << iNum << endl;
int * p = get_pointer<int>(a);//获得a内部元素的指针
cout << *p << endl;
get_reference<int>(a) = 5;//获得a内部元素引用,引用可以被当做左值来使用
cout << *p << endl;
if (match_type<int>(a))//判断a内部元素类型是否为int
cout << "true" << endl;
return 0;
}
tuple:
tuple类型类似于std::pair,pair只支持包含两种类型的元素,tuple可以支持包含多个不同类型的元素,比如将其用于多个返回值的函数的话比使用struct更方便.
用法:
#include <cstdio>
#include <string>
using std::string;
#include "boost/tuple/tuple.hpp"
int main()
{
int i = 1;
double d = 5.0;
string s("hello");
//tuple<int,double,string>
auto tupleCombin = make_tuple(i,d,s);
//tuple<const int&,double&,string>
auto tupleCombin_2 = make_tuple(cref(i),ref(d),s);
BOOST_ASSERT(tupleCombin.get<0>() == 1);
BOOST_ASSERT(tupleCombin.get<1>() == 5.0);
return getchar();
}
variant:
variant是一种增强的union,C/C++中union只能持有POD(普通数据类型),而不能持有如string、vector等复杂类型,boost的variant则没有这个限制。
用法:
#include<boost/variant.hpp>
int main()
{
variant<int,float,string> v;
v = "123";
cout <<v <<endl;
try
{
cout << get<float>(v)<<endl;
}
catch(boost::bad_get&)
{
cout <<"bad_get"<<endl;
}
if(v.type() == typeid(int))
{
cout << get<int>(v) <<endl;
}
else if(v.type() == typeid(double))
{
cout << get<double>(v) <<endl;
}
}