Boost.Variant, part of collection of the Boost C++ Libraries. It is a safe, generic, stack-based discriminated union container, offering a simple solution for manipulating an object from a heterogeneous set of types in a uniform manner.
@ | Build | Tests coverage | More info |
---|---|---|---|
Develop branch: | details... | ||
Master branch: | details... |
Latest developer documentation
The variant
class template is a safe, generic, stack-based discriminated union container, offering a simple solution for manipulating an object from a heterogeneous set of types in a uniform manner. Whereas standard containers such as std::vector
may be thought of as "multi-value, single type," variant
is "multi-type, single value."
Notable features of boost::variant
include:
boost::apply_visitor
.boost::get
.boost::make_recursive_variant
and boost::recursive_wrapper
.Solution: A Motivating Example
Many times, during the development of a C++ program, the programmer finds himself in need of manipulating several distinct types in a uniform manner. Indeed, C++ features direct language support for such types through its union
keyword:
union { int i; double d; } u;
u.d = 3.14;
u.i = 3; // overwrites u.d (OK: u.d is a POD type)
C++'s union
construct, however, is nearly useless in an object-oriented environment. The construct entered the language primarily as a means for preserving compatibility with C, which supports only POD (Plain Old Data) types, and so does not accept types exhibiting non-trivial construction or destruction:
union {
int i;
std::string s; // illegal: std::string is not a POD type!
} u;
Clearly another approach is required. Typical solutions feature the dynamic-allocation of objects, which are subsequently manipulated through a common base type (often a virtual base class [Hen01] or, more dangerously, a void*
). Objects of concrete type may be then retrieved by way of a polymorphic downcast construct (e.g., dynamic_cast
, boost::any_cast
, etc.).
However, solutions of this sort are highly error-prone, due to the following:
Furthermore, even when properly implemented, these solutions tend to incur a relatively significant abstraction penalty due to the use of the heap, virtual function calls, and polymorphic downcasts.
The boost::variant
class template addresses these issues in a safe, straightforward, and efficient manner. The following example demonstrates how the class can be used:
#include "boost/variant.hpp"
#include <iostream>
class my_visitor : public boost::static_visitor<int>
{
public:
int operator()(int i) const
{
return i;
}
int operator()(const std::string & str) const
{
return str.length();
}
};
int main()
{
boost::variant< int, std::string > u("hello world");
std::cout << u; // output: hello world
int result = boost::apply_visitor( my_visitor(), u );
std::cout << result; // output: 11 (i.e., length of "hello world")
}
Author: boostorg
Source: https://github.com/boostorg/variant