anyanybad_any_castany_castint and string, and freely convert between them,
for instance interpreting 5 as "5" or vice-versa.
Such types are common in scripting and other interpreted languages.
boost::lexical_cast supports such conversion functionality.
5 is held strictly as an int and is not implicitly
convertible either to "5" or to 5.0. Their indifference to
interpretation but awareness of type effectively makes them safe, generic containers of single
values, with no scope for surprises from ambiguous conversions.
void *, which offers plenty of scope for surprising, undefined behavior.
any class ("Valued Conversions",
C++ Report 12(7), July/August 2000) is a variant value type
based on the second category. It supports copying of any value type and safe, checked extraction of that
value strictly against its type.
any objects:
using namespace std;
using namespace boost;
list<any> values;
void append_int(int value)
{
any to_append = value;
values.push_back(to_append);
}
void append_string(const string & value)
{
values.push_back(value);
}
void append_char_ptr(const char * value)
{
values.push_back(value);
}
void append_any(const any & value)
{
values.push_back(value);
}
void append_nothing()
{
values.push_back(any());
}
The following predicates follow on from the previous definitions and demonstrate
the use of queries on any objects:
bool is_empty(const any & operand)
{
return operand;
}
bool is_int(const any & operand)
{
return operand.type() == typeid(int);
}
bool is_char_ptr(const any & operand)
{
const char * unused;
return operand.copy_to(unused);
}
bool is_string(const any & operand)
{
return operand.to_ptr<string>();
}
void count_all()
{
cout << "#empty == "
<< count_if(values.begin(), values.end(), is_empty) << endl;
cout << "#int == "
<< count_if(values.begin(), values.end(), is_int) << endl;
cout << "#const char * == "
<< count_if(values.begin(), values.end(), is_char_ptr) << endl;
cout << "#string == "
<< count_if(values.begin(), values.end(), is_string) << endl;
}
The following type, patterned after the OMG's Property Service, defines namevalue
pairs for arbitrary value types:
struct property
{
property();
property(const std::string &, const boost::any &);
std::string name;
boost::any value;
};
typedef 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;
...
};
"any.hpp":
#include <typeinfo>
namespace boost
{
class any;
class bad_any_cast;
template<typename ValueType>
ValueType any_cast(const any &);
}
Test harness defined in "test-any.cpp".
As the emphasis of a value lies in its state not its identity, values can be copied and typically assigned one to another, requiring the explicit or implicit definition of a public copy constructor and public assignment operator. Values typically live within other scopes, i.e. within objects or blocks, rather than on the heap. Values are therefore normally passed around and manipulated directly as variables or through references, but not as pointers that emphasize identity and indirection.
The specific requirements on value types to be used in an any are:
any::copy_to requires this optional capability.
any
class any
{
public: // structors
any();
any(const any &);
template<typename ValueType>
any(const ValueType &);
~any();
public: // modifiers
any & swap(any &);
any & operator=(const any &);
template<typename ValueType>
any & operator=(const ValueType &);
public: // queries
operator const void *() const;
const std::type_info & type() const;
template<typename ValueType>
bool copy_to(ValueType &) const;
template<typename ValueType>
ValueType * to_ptr();
template<typename ValueType>
const ValueType * to_ptr() const;
private: // representation
...
};
An exception-safe class whose instances can hold instances of any type that satisfies
ValueType requirements: effectively an unbounded union type.
Note that any itself satisfies ValueType requirements.
Default constructor that sets new instance to empty.any::any();
Copy constructor that copies content ofany::any(const any & other);
other into new instance, so that
any content is equivalent in both type and value to the content of other,
or empty if other is empty. May fail with a std::bad_alloc exception
or any exceptions arising from the copy constructor of the contained type.
Templated constructor makes a copy oftemplate<typename ValueType> any::any(const ValueType & value);
value, so that the initial content of the
new instance is equivalent in both type and value to value. May fail with a
std::bad_alloc exception or any exceptions arising from the copy constructor of
the contained type.
Non-throwing destructor that releases any and all resources used in management of instance.any::~any();
Non-throwing swap of the contents ofany & swap(any & rhs);
*this and rhs.
Copy assignment operator that copies content ofany & operator=(const any & rhs);
rhs into current instance, discarding
previous content, so that the new content is equivalent in both type and value to the content of
rhs, or empty if rhs is empty. May fail with a std::bad_alloc
exception or any exceptions arising from the copy constructor of the contained type.
Assignment satisfies the strong guarantee of exception safety.
Templated assignment operator makes a copy oftemplate<typename ValueType> any & operator=(const ValueType & rhs);
rhs, discarding previous content,
so that the new content of is equivalent in both type and value to rhs. May fail with a
std::bad_alloc exception or any exceptions arising from the copy constructor of
the contained type. Assignment satisfies the strong guarantee of exception safety.
Test for emptiness, returning null if instance is empty, otherwise a single, unspecified non-null pointer.operator const void *() const;
Returns theconst std::type_info & type() const;
typeid of the contained value if instance is non-empty, otherwise
typeid(void) returned. Useful for querying against types known either at
compile time or only at runtime.
Extraction of instance content by assignment. Returnstemplate<typename ValueType> bool copy_to(ValueType & value) const;
true and assigns content
of instance to value if typeid(ValueType) == type(), otherwise
returns false and does not modify value. This combined test and
assign value form can be more concise than either
any::to_ptr or any_cast
where a variable assignment is required, but exception handling or additional variable
declarations would be considered verbose.
Extraction of pointer to instance content. Returns a correctly cast pointer to the contained value iftemplate<typename ValueType> ValueType * to_ptr(); template<typename ValueType> const ValueType * to_ptr() const;
typeid(ValueType) == type(), otherwise returns null. Top-level
cv-qualification of ValueType is ignored. to_ptr is used
normally for extracting content without a strong assumption that the query will succeed. It
can also be used to support type queries against a type known at compile time.
bad_any_cast
class bad_any_cast : public std::bad_cast
{
public:
virtual const char * what() const;
};
The exception thrown in the event of a failed any_cast.
any_castCustom keyword cast for extracting a value of a given type from antemplate<typename ValueType> ValueType any_cast(const any & operand);
any. Returns a copy of the extracted result if successful,
otherwise a bad_any_cast exception is thrown.
any_cast is used normally for conversions that are expected to succeed.
any::to_ptr
is not supported.
boost directory structure and use of <boost/config.hpp>.