Boost::any Usage Example:
#include <iostream>#include<list>#include<boost/any.hpp>typedef std::list<boost::any>List_any;//key part: Can hold any type of objectvoidFill_list (list_any&LA) {La.push_back (Ten);//Store ConstantsLa.push_back (std::string("Dyunze") );//Store String object, note la.push_back ("Dyunze") error because it will be the wrong string array}//Display by TypevoidShow_list (list_any&LA) {List_any::iterator it; Boost::any anyone; for(it = La.begin (); It! = La.end (); it++) {Anyone= *it; if(Anyone.type () = = typeID (int)) Std::cout<<boost::any_cast<int> (*it) <<Std::endl; Else if(Anyone.type () = = typeID (std::string)) Std::cout<<BOOST::ANY_CAST<STD::string> (*it). C_STR () <<Std::endl; }}intMain () {list_any LA; Fill_list (LA); Show_list (LA); return 0;}
Advantages of Boost::any:
A friend who understands the design pattern knows the compositing pattern. Because polymorphism can only be manifested with pointers or references, the STD container can only hold pointers or references (but it can actually hold pointers and cannot hold references, which seems to be a lack of C + +). Such as:
Std::list<baseclass*> MyList;
In this way, we have to worry about the lifetime of the content pointed to by the pointer (which may require the programmer to delete the requested memory at the appropriate time, but because of the efficient insertion/deletion of the pointer), the use of boost::any may avoid this situation, because we can store the type itself (of course, the pointer can be stored). This is one of the advantages of Boost::any.
Boost::any Another advantage is that you can store any type. The previously mentioned mylist can only hold pointers to BaseClass class pointers and their inherited classes.
Disadvantages of Boost::any:
Since boost::any can store any type, naturally it cannot use polymorphic features, there is no unified interface, so it is necessary to implement the true type of discriminant elements when acquiring elements in the container, which increases the burden on the programmer. There are some contradictions with object-oriented programming, but the whole standard C + + Template Library is not so, and in the words of those cows, it is a "useful supplement".
In short, there are pros and cons, there is no perfect.
Analyze and imitate Boost::any:
Read the source code of the Boost::any, and imitate the implementation (a significant part of the original code), the following is the code (only the necessary functions).
The ability to implement any is composed of three main parts:
1) Any class
2) the holder class and its base class that really holds the data placeholder
3) Get the function of real data template function Any_cast, type conversion.
#include <iostream>#include<list>#include<cassert>//Custom any classclassany{ Public: //the interface class that holds the real data classPlaceholder { Public: Virtual~placeholder () {} Public: Virtual ConstStd::type_info & Type ()Const=0; VirtualPLACEHOLDER * Clone ()Const=0; }; //the class that really saves and gets the data. Template<typename valuetype>classHolder: PublicPlaceholder { Public: Holder (ConstValueType &value): Held (value) {} Public: Virtual ConstStd::type_info & Type ()Const { returntypeid (ValueType); } VirtualPLACEHOLDER * Clone ()Const { return NewHolder (held);//using the prototype mode } Public: //real data, just keep it here .ValueType held; }; Public: Any (): content (NULL) {}//template constructors, parameters can be any type, real data is stored in contentTemplate<typename valuetype>Any (ConstValueType & Value): Content (NewHolder<valuetype>(value)) { } //copy ConstructorAnyConstAny &Other ): content (Other.content? Other.content->clone ():0) { } //destructor to delete the content object that holds the data~Any () {if(NULL! =content)Deletecontent; }Private: //An implementation of a Placeholde object pointer to its subclass folder//that is, the content (new holder<valuetype> (value)) statementplaceholder*content; Template<typename valuetype> friend ValueType Any_cast (Constany&operand); Public: //Query the type of real data. ConstStd::type_info & Type ()Const { returnContent? Content->type (): typeID (void); }};//gets the method that content->helder the data. To get real data.Template<typename valuetype>ValueType Any_cast (Constany&operand) {Assert (Operand.type ()==typeid (ValueType)); returnStatic_cast<any::holder<valuetype> *> (operand.content)held;}//The following code is an example of usingtypedef std::list<any>List_any;voidFill_list (list_any&LA) {La.push_back (Ten);//The template constructor for any is called, and theLa.push_back (std::string("I'm a string .") );//Store String object, note la.push_back ("Dyunze") error because it will be the wrong string array Char* p ="I am the constant area string ABC"; La.push_back (p);//you can store pointers, but pay attention to the failure of pointers}//Display by TypevoidShow_list (list_any&LA) {List_any::iterator it; for(it = La.begin (); It! = La.end (); it++ ) { if((*it). Type () = = typeID (int)) Std::cout<<any_cast<int> (*it) <<Std::endl; Else if((*it). Type () = = typeID (std::string)) Std::cout<<ANY_CAST<STD::string> (*it). C_STR () <<Std::endl; Else if((*it). Type () = = typeID (Char*)) Std::cout<<any_cast<Char*> (*it) <<Std::endl; }}intMain () {list_any LA; Fill_list (LA); Show_list (LA); return 0;}
Reference documents
1) http://www.nohack.cn/code/other/2006-10-05/10230.html
2) Boost::any Source code
[Go] boost::any usage, pros and cons, and source code analysis