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