boost::any 用法


boost::any可以存放任何類型的C++類型,也可以是用戶自定義的類型。非常方便,可以很方便的滿足在運行過程中判斷數據類型,從而進行相關的操作。

函數原型:

// In header: <boost/any.hpp>


class any {
public:
  // construct/copy/destruct
  any();
  any(const any &);
  template<typename ValueType> any(const ValueType &);
  any & operator=(const any &);
  template<typename ValueType> any & operator=(const ValueType &);
  ~any();

  // modifiers
  any & swap(any &);

  // queries
  bool empty() const;
  const std::type_info & type() const;
};

成員函數說明:

 

   Boost::Any的實現比較簡單,Any擁有一個模版構造函數,這使他可以接受任何類型的對象。真正的變量內容被封裝在嵌套類類型的成員變量中,並且在嵌套類中使用typeid來記錄真正的類型信息。

  1) any& swap(any& other);交換存在兩個 any 對象中的值。
  2) any& operator=(const any& other);如果any實例非空,則丟棄所存放的值,並存入other值的拷貝。
  3)template<typename ValueType>  any& operator=(const ValueType& value);如果any實例非空,則丟棄所存放的值,並存入 value 的一份拷貝,value可以是任意符合any要求的類型。
  4) bool empty() const;給出any實例當前是否有值,不管是什么值。因而,當any持有一個指針時,即使該指針值為空,則 empty也返回 false 。
  5) const std::type_info& type() const;給出所存值的類型。如果 any 為空,則類型為 void.
  6) any_cast()將any類型轉化為真實的類型,如果是指針返回的可能是空指針,如果非指針,則可能會拋出異常。

三 實例

1)簡單實例以及調用常用的成員函數:

#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include "boost/any.hpp"

class A 
{
public:  
    void some_function() 
    { 
        std::cout << "A::some_function()\n"; 
    }
};
class B
{
public:  
    void some_function() 
    { 
        std::cout << "B::some_function()\n"; 
    }
};

void print_any(boost::any& a)
{  
    if (A* pA=boost::any_cast<A>(&a)) 
    {   
        pA->some_function();  
    }  
    else if (B* pB=boost::any_cast<B>(&a))
    {   
        pB->some_function();  
    }      
    else
    {   
        try 
        {     
            std::cout << boost::any_cast<std::string>(a) << '\n';   
        }   
        catch(boost::bad_any_cast&) 
        {     
            std::cout << "Oops!\n";   
        }  
    }
}

int main() 
{  
    std::cout << "Example of using any.\n\n"; 
    std::vector<boost::any> store_anything;  
    store_anything.push_back(A());  
    store_anything.push_back(B());  
    // 我們再來,再加一些別的東西  
    store_anything.push_back(std::string("This is fantastic! "));  
    store_anything.push_back(3);  
    store_anything.push_back(std::make_pair(true, 7.92));     
    std::for_each(  store_anything.begin(),  store_anything.end(),  print_any);


     std::cout << "Example of using any member functions\n\n"; 
     boost::any a1(100); 
     boost::any a2(std::string("200"));  
     boost::any a3; 
     std::cout << "a3 is "; 
     if (!a3.empty()) 
     {    
         std::cout << "not empty\n "; 
     }  
     std::cout << "empty\n";  
     a1.swap(a2); 
     try 
     {   
         std::string s=boost::any_cast<std::string>(a1); 
         std::cout << "a1 contains a string: " << s << "\n"; 
     } 
     catch(boost::bad_any_cast& e) 
     {  
         std::cout << "I guess a1 doesn't contain a string!\n"; 
     } 
     if (int* p=boost::any_cast<int>(&a2)) 
     {  
         std::cout << "a2 seems to have swapped contents with a1: "      << *p << "\n"; 
     } 
     else
     {    
         std::cout << "Nope, no int in a2\n"; 
     }  
     if (typeid(int)==a2.type()) 
     {    
         std::cout << "a2's type_info equals the type_info of int\n";  
     }

}
 

2)解決類似與map但是可以映射到各種不同的類型的問題:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/any.hpp"
class property
{  
    boost::any value_;
    std::string name_;
public:  
    property(const std::string& name,const boost::any& value)  
        : name_(name),value_(value) {}  
    std::string name() const { return name_; } 
    boost::any& value() { return value_; } 
    friend bool operator<(const property& lhs, const property& rhs)
    {return lhs.name_<rhs.name_;}
};
void print_names(const property& p) 
{ 
    std::cout << p.name() << "\n";
}
int main() 
{  
    std::cout << "Example of using any for storing properties.\n";
    std::vector<property> properties; 
    properties.push_back(  property("B", 30));
    properties.push_back(  property("A", std::string("Thirty something"))); 
    properties.push_back(property("C", 3.1415));  
    std::sort(properties.begin(),properties.end());
    std::for_each(properties.begin(),  properties.end(),  print_names);
    std::cout << "\n";  
    std::cout <<  boost::any_cast<std::string>(properties[0].value()) << "\n"; 
    std::cout <<  boost::any_cast<int>(properties[1].value()) << "\n"; 
    std::cout <<  boost::any_cast<double>(properties[2].value()) << "\n";    
}

四 注意

1)Any中如果是指針,要注意指針的最后的釋放,最好使用shared_ptr來管理。
2)Any中如果是指針,如果Any.isempty()返回false,但是any所包含的指針仍可能是無效的。
3)Any中如果是指針,則在調用any_cast()轉化的過程中不會拋出異常,但是如果是一般變量或引用的話,類型不正確會拋出boost::bad_any_cast異常。

五 參考

1)Beyond the C++ Standard Library: An Introduction to Boost
2)boost在線document

參考:http://www.cppblog.com/mzty/archive/2007/08/16/30156.html

any類實現:

boost::any類並不是一個模板類,這可以大大的方便上層應用的使用,它會自動化的類型轉換。核心就是any類中,包含一個模板類holder的基類placeholder指針,而placeholder卻不是模板類,這樣就可以被any類使用了。

具體的如下面所示:

http://www.cnblogs.com/wuerping/articles/116414.html

更多:http://blog.csdn.net/hityct1/article/details/4186962

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM