...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::variant — Safe, generic, stack-based discriminated union container.
template<typename T1, typename T2 = unspecified, ..., typename TN = unspecified> class variant { public: // types typedef unspecified types; // construct/copy/destruct variant(); variant(const variant &); template<typename T> variant(T &); template<typename T> variant(const T &); template<typename U1, typename U2, ..., typename UN> variant(variant<U1, U2, ..., UN> &); template<typename U1, typename U2, ..., typename UN> variant(const variant<U1, U2, ..., UN> &); ~variant(); // modifiers void swap(variant &); variant & operator=(const variant &); template<typename T> variant & operator=(const T &); // queries int which() const; bool empty() const; const std::type_info & type() const; // relational bool operator==(const variant &) const; template<typename U> void operator==(const U &) const; bool operator<(const variant &) const; template<typename U> void operator<(const U &) const; };
The variant
class template (inspired by Andrei
Alexandrescu's class of the same name
[Ale01A]) is an efficient,
recursive-capable,
bounded discriminated union value type capable of containing any value
type (either POD or non-POD). It supports construction from any type
convertible to one of its bounded types or from a source
variant
whose bounded types are each convertible to one
of the destination variant
's bounded types. As well,
through apply_visitor
,
variant
supports compile-time checked, type-safe
visitation; and through get
,
variant
supports run-time checked, type-safe value
retrieval.
Notes:
variant
are exposed
via the nested typedef types
, which is an
MPL-compatible Sequence containing the
set of types that must be handled by any
visitor to
the variant
.variant
satisfy at least the
basic guarantee of exception-safety. That is, all operations on
a variant
remain defined even after previous
operations have failed.variant
must meet the requirements of the
BoundedType
concept.variant
must be distinct after removal of qualifiers.
Thus, for instance, both variant<int, int>
and
variant<int, const int>
have undefined
behavior.variant
must
allow at least ten types as template arguments. The exact number
of allowed arguments is exposed by the preprocessor macro
BOOST_VARIANT_LIMIT_TYPES
.
(See make_variant_over
for a
means to specify the bounded types of a variant
by
the elements of an MPL or compatible
Sequence, thus overcoming this limitation.)variant
construct/copy/destructvariant();
Requires:
The first bounded type of the variant
(i.e.,
T1
) must fulfill the requirements of the
DefaultConstructible [20.1.4]
concept.
Postconditions:
Content of *this
is the default value of the
first bounded type (i.e, T1
).
Throws:
May fail with any exceptions arising from the default
constructor of T1
.
variant(const variant & other);
Postconditions:
Content of *this
is a copy of the content of
other
.
Throws:
May fail with any exceptions arising from the
copy constructor of other
's contained type.
template<typename T> variant(T & operand);
Requires:
T
must be unambiguously convertible to one of
the bounded types (i.e., T1
, T2
,
etc.).
Postconditions:
Content of *this
is the best conversion of
operand
to one of the bounded types, as determined
by standard overload resolution rules.
Throws:
May fail with any exceptions arising from the conversion of
operand
to one of the bounded types.
template<typename T> variant(const T & operand);
Notes: Same semantics as previous constructor, but allows construction from temporaries.
template<typename U1, typename U2, ..., typename UN> variant(variant<U1, U2, ..., UN> & operand);
Requires:
Every one of U1
,
U2
, ..., UN
must have an unambiguous
conversion to one of the bounded types (i.e., T1
,
T2
, ..., TN
).
Postconditions:
If variant<U1, U2, ..., UN>
is itself
one of the bounded types, then content of *this
is a
copy of operand
. Otherwise, content of
*this
is the best conversion of the content of
operand
to one of the bounded types, as determined
by standard overload resolution rules.
Throws:
If variant<U1, U2, ..., UN>
is itself
one of the bounded types, then may fail with any exceptions arising
from the copy constructor of
variant<U1, U2, ..., UN>
. Otherwise, may fail
with any exceptions arising from the conversion of the content of
operand
to one of the bounded types.
template<typename U1, typename U2, ..., typename UN> variant(const variant<U1, U2, ..., UN> & operand);
Notes: Same semantics as previous constructor, but allows construction from temporaries.
~variant();
Effects:
Destroys the content of *this
.
Throws:
Will not throw.
variant
modifiersvoid swap(variant & other);
Requires:
Every bounded type must fulfill the requirements of the
Assignable
concept.
Effects:
Interchanges the content of *this
and
other
.
Throws:
If the contained type of other
is the same as
the contained type of *this
, then may fail with any
exceptions arising from the swap
of the contents of
*this
and other
. Otherwise, may fail
with any exceptions arising from either of the copy constructors
of the contained types. Also, in the event of insufficient
memory, may fail with std::bad_alloc
(why?).
variant & operator=(const variant & rhs);
Requires:
Every bounded type must fulfill the requirements of the
Assignable
concept.
Effects:
If the contained type of rhs
is the same as
the contained type of *this
, then assigns the
content of rhs
into the content of
*this
. Otherwise, makes the content of
*this
a copy of the content of rhs
,
destroying the previous content of *this
.
Throws:
If the contained type of rhs
is the same as
the contained type of *this
, then may fail with any
exceptions arising from the assignment of the content of
rhs
into the content *this
. Otherwise,
may fail with any exceptions arising from the copy constructor
of the contained type of rhs
. Also, in the event of
insufficient memory, may fail with std::bad_alloc
(why?).
template<typename T> variant & operator=(const T & rhs);
Requires:
T
must be unambiguously convertible to
one of the bounded types (i.e., T1
,
T2
, etc.).*this
is
T
, then assigns rhs
into the content
of *this
. Otherwise, makes the content of
*this
the best conversion of rhs
to
one of the bounded types, as determined by standard overload
resolution rules, destroying the previous content of
*this
.*this
is
T
, then may fail with any exceptions arising from
the assignment of rhs
into the content
*this
. Otherwise, may fail with any exceptions
arising from the conversion of rhs
to one of the
bounded types. Also, in the event of insufficient memory, may
fail with std::bad_alloc
(why?).
variant
queriesint which() const;
Returns:
The zero-based index into the set of bounded types
of the contained type of *this
. (For instance, if
called on a variant<int, std::string>
object
containing a std::string
, which()
would return 1
.)
Throws:
Will not throw.
bool empty() const;
Returns:
false
: variant
always contains
exactly one of its bounded types. (See
the section called “"Never-Empty" Guarantee”
for more information.)
Rationale:
Facilitates generic compatibility with
boost::any.
Throws:
Will not throw.
const std::type_info & type() const;
Returns:
typeid(x)
, where x
is the the
content of *this
.
Throws:
Will not throw.
variant
relationalbool operator==(const variant & rhs) const; template<typename U> void operator==(const U & ) const;
Notes:
The overload returning void
exists only to
prohibit implicit conversion of the operator's right-hand side
to variant
; thus, its use will (purposefully)
result in a compile-time error.
Requires:
Every bounded type of the variant
must
fulfill the requirements of the
EqualityComparable
concept.
Returns:
true
iff which() == rhs.which()
andcontent_this == content_rhs
, where
content_this
is the content of *this
and content_rhs
is the content of
rhs
.
Throws:
If which() == rhs.which()
then may fail with
any exceptions arising from operator==(T,T)
, where
T
is the contained type of
*this
.
bool operator<(const variant & rhs) const; template<typename U> void operator<(const U & ) const;
Notes:
The overload returning void
exists only to
prohibit implicit conversion of the operator's right-hand side
to variant
; thus, its use will (purposefully)
result in a compile-time error.
Requires:
Every bounded type of the variant
must
fulfill the requirements of the
LessThanComparable
concept.
Returns:
If which() == rhs.which()
then:
content_this < content_rhs
, where
content_this
is the content of *this
and content_rhs
is the content of rhs
.
Otherwise: which() < rhs.which()
.
Throws:
If which() == rhs.which()
then may fail with
any exceptions arising from operator<(T,T)
,
where T
is the contained type of
*this
.
Copyright © 2002, 2003 Eric Friedman, Itay Maman |