boost总结之variant


boost的variant库类似于联合体,但是联合体中只能接受POD类型,但variant中并无此限制,它可以接受任意的类型.
 
boost::variant <int, std::string , double> u;
u  = 4;
int i = boost:: get<int >(u);
std::cout << "int : " << i << std ::endl;
 
u = "hello world!" ;
std::string s = boost::get <std:: string>(u );
std::cout << "string : " << s << std ::endl;
 
u  = 1.2;
double d = boost:: get<double >(u);
std::cout << "double : " << d << std ::endl;
 
输出:
int : 4
string : hello world!
double : 1.2
 
要获取variant中的值时,一定要知道当前类型,并由get操作进行获取相应的值,如果转型失败,会抛出bad_get异常,get操作时运行时检测,我们可以通过检测get返回值来进行判断转型是否成功如下:
 
void  printer  ( boost ::  variant < int  ,  std ::  string ,  double  >&  u )
{
     if  ( int  * pi  =  boost :: get  < int >(&  u ))
    {
         std :: cout  <<  "int : "  << *  pi  <<  std  :: endl ;
    }
     else  if  ( std ::  string  * ps  =  boost ::  get < std  :: string >(&  u ))
    {
         std :: cout  <<  "string : "  << *  ps  <<  std  :: endl ;
    }
     else  if  ( double  *  pd  =  boost  :: get <  double >(& u  ))
    {
         std :: cout  <<  "double : "  << *  pd  <<  std  :: endl ;
    }
}
 
通过printer函数中我们为get传进去的是variant的地址,返回如果是NULL的话则转型失败,进行下一个转型操作,依次来判断数据类型.可以看到通过get操作不仅需要知道需要转型的类型,而且还要在运行时判断转型是否成功,boost提供了编译时类型检测的安全访问方式,通过apply_visitor进行访问.
 
class  printer_visitor  :  public  boost :: static_visitor  < void >
{
public :
     void  operator  ()( int  i )  const
    {
         std :: cout  <<  "int : "  <<  i  <<  std  :: endl ;
    }
 
     void  operator  ()( std ::  string &  s  )  const
    {
         std :: cout  <<  "string : "  <<  s  <<  std  :: endl ;
    }
 
     void  operator  ()( double  d )  const
    {
         std :: cout  <<  "double : "  <<  d  <<  std  :: endl ;
    }
};
int  main  ()
{
     boost :: variant  < int ,  std :: string  ,  double >  u ;
     printer_visitor  visitor  ;
     u  = 4;
     boost :: apply_visitor  ( visitor ,  u );
     u  =  "hello world!"  ;
     boost :: apply_visitor  ( visitor ,  u );
     u  = 1.2;
     boost :: apply_visitor  ( visitor ,  u );
}
 
我们定义一个variant时,如果我们没有给它赋任何值时,是不是他就是空呢?boost文档中 "Never-Empty" Guarantee.也就是即使我们没有初始化,他也不会是空,默认的类型是我们模板参数的第一个,上例中默认的类型也就是int,值是0.
 
我们还可以将variant作为容器的元素例如:
 
std :: vector  < boost ::  variant < int  ,  std ::  string ,  double  > >  v ;
v . push_back  (4);
v . push_back  ( "hello world!" );
v . push_back  (1.2);
std :: for_each  ( v .  begin (),  v  . end (),  boost :: apply_visitor  ( printer_visitor ()));


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM