ConceptsBoundedTypeThe requirements on a bounded type
are as follows:CopyConstructible or MoveConstructible.Destructor upholds the no-throw exception-safety
guarantee.Complete at the point of variant template
instantiation. (See
boost::recursive_wrapper<T>
for a type wrapper that accepts incomplete types to enable recursive
variant types.)Every type specified as a template argument to
variant must at minimum fulfill the
above requirements. In addition, certain features of variant
are available only if its bounded types meet the requirements of these
following additional concepts:Assignable:
variant is itself Assignable if and
only if every one of its bounded types meets the requirements of the
concept. (Note that top-level const-qualified types and
reference types do not meet these
requirements.)MoveAssignable:
variant is itself MoveAssignable if and
only if every one of its bounded types meets the requirements of the
concept. (Note that top-level const-qualified types and
reference types do not meet these
requirements.)DefaultConstructible [20.1.4]:
variant is itself
DefaultConstructible if and only if its first
bounded type (i.e., T1) meets the requirements of the
concept.EqualityComparable:
variant is itself EqualityComparable
if and only if every one of its bounded types meets the requirements
of the concept.LessThanComparable:
variant is itself LessThanComparable
if and only if every one of its bounded types meets the requirements
of the concept.OutputStreamable:
variant is itself OutputStreamable
if and only if every one of its bounded types meets the requirements
of the concept.Hashable:
variant is itself Hashable
if and only if every one of its bounded types meets the requirements
of the concept.StaticVisitorThe requirements on a static
visitor of a type T are as follows:Must allow invocation as a function by overloading
operator(), unambiguously accepting any value of type
T.Must expose inner type result_type. C++14 compatible compilers
could detect result_type automatically, but will stick to
result_type if it is defined. (See
boost::visitor_ptr for a
solution to using functions as visitors.)If result_type is not void, then
each operation of the function object must return a value implicitly
convertible to result_type.ExamplesThe following class satisfies the requirements of a static visitor
of several types (i.e., explicitly: int and
std::string; or, e.g., implicitly: short and
const char *; etc.):class my_visitor
: public boost::static_visitor<int>
{
public:
int operator()(int i)
{
return i * 2;
}
int operator()(const std::string& s)
{
return s.length();
}
};Another example is the following class, whose function-call
operator is a member template, allowing it to operate on values of many
types. Thus, the following class is a visitor of any type that supports
streaming output (e.g., int, double,
std::string, etc.):class printer
: public boost::static_visitor<>
{
template <typename T>
void operator()(const T& t)
{
std::cout << t << std::endl;
}
};C++14 compatible compilers detect result_type automatically:boost::variant<int, float> v;
// ...
boost::apply_visitor(
[](auto val) { return std::to_string(val); },
v
);
OutputStreamableThe requirements on an output
streamable type T are as follows:For any object t of type T,
std::cout << t must be a valid
expression.HashableThe requirements on an hashable type T are as follows:For any object t of type T,
boost::hash<T>()(t) must be a valid
expression.