...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The following code demonstrates the syntax for using implicit conversions to and copying of any objects:
#include <list> #include <boost/any.hpp> usingboost::any_cast
; typedef std::list<boost::any
> many; void append_int(many & values, int value) {boost::any
to_append = value; values.push_back(to_append); } void append_string(many & values, const std::string & value) { values.push_back(value); } void append_char_ptr(many & values, const char * value) { values.push_back(value); } void append_any(many & values, constboost::any
& value) { values.push_back(value); } void append_nothing(many & values) { values.push_back(boost::any
()); }
The following predicates follow on from the previous definitions and demonstrate the use of queries on any objects:
bool is_empty(constboost::any
& operand) { return operand.empty
(); } bool is_int(constboost::any
& operand) { return operand.type
() == typeid(int); } bool is_char_ptr(constboost::any
& operand) { try {any_cast
<const char *>(operand); return true; } catch(constboost::bad_any_cast
&) { return false; } } bool is_string(constboost::any
& operand) { returnany_cast
<std::string>(&operand); } void count_all(many & values, std::ostream & out) { out << "#empty == " << std::count_if(values.begin(), values.end(), is_empty) << std::endl; out << "#int == " << std::count_if(values.begin(), values.end(), is_int) << std::endl; out << "#const char * == " << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl; out << "#string == " << std::count_if(values.begin(), values.end(), is_string) << std::endl; }
The following type, patterned after the OMG's Property Service, defines name-value pairs for arbitrary value types:
struct property { property(); property(const std::string &, constboost::any
&); std::string name;boost::any
value; }; typedef std::list<property> properties;
The following base class demonstrates one approach to runtime polymorphism based callbacks that also require arbitrary argument types. The absence of virtual member templates requires that different solutions have different trade-offs in terms of efficiency, safety, and generality. Using a checked variant type offers one approach:
class consumer
{
public:
virtual void notify(const any
&) = 0;
...
};