| Home | Libraries | People | FAQ | More

## Reference

### Concepts

#### BoundedType

The 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.

#### StaticVisitor

The 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`.

##### Examples

The 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
        );

#### OutputStreamable

The 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.

#### Hashable

The 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.

### Header <boost/variant.hpp>

This header exists simply as a convenience to the user, including all of the headers in the `boost/variant` directory except <boost/multivisiors.hpp>.

### Header <boost/variant/variant_fwd.hpp>

Provides forward declarations of the `boost::variant`, `boost::make_variant_over`, `boost::make_recursive_variant`, and `boost::make_recursive_variant_over` class templates and the `boost::recursive_variant_` tag type. Also defines several preprocessor symbols, as described below.

    BOOST_VARIANT_LIMIT_TYPES
    BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
    BOOST_VARIANT_ENUM_PARAMS(param)
    BOOST_VARIANT_ENUM_SHIFTED_PARAMS(param)
    BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
    BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT

### Header <boost/variant/variant.hpp>

    namespace boost {
      template<typename T1, typename T2 = unspecified, ...,
               typename TN = unspecified>
        class variant;

      template<typename Sequence> class make_variant_over;
      template<typename T1, typename T2, ..., typename TN>
        void swap(variant<T1, T2, ..., TN> &, variant<T1, T2, ..., TN> &);
      template<typename ElemType, typename Traits, typename T1, typename T2, ...,
               typename TN>
        std::basic_ostream<ElemType,Traits> &
        operator<<(std::basic_ostream<ElemType,Traits> &,
                   const variant<T1, T2, ..., TN> &);
      template<typename T1, typename T2, ..., typename TN>
        std::size_t hash_value(const variant<T1, T2, ..., TN> &);
    }

### Header <boost/variant/recursive_variant.hpp>

    namespace boost {
      typedef unspecified recursive_variant_;

      template<typename T1, typename T2 = unspecified, ...,
               typename TN = unspecified>
        class make_recursive_variant;
      template<typename Sequence> class make_recursive_variant_over;
    }

### Header <boost/variant/recursive_wrapper.hpp>

    namespace boost {
      template<typename T> class recursive_wrapper;
      template<typename T> class is_recursive_wrapper;
      template<typename T> class unwrap_recursive_wrapper;
    }

### Header <boost/variant/apply_visitor.hpp>

    namespace boost {
      template<typename Visitor> class apply_visitor_delayed_t;
      template<typename Visitor> class apply_visitor_delayed_cpp14_t;
      template<typename Visitor, typename Variant>
        typename Visitor::result_type apply_visitor(Visitor &, Variant&&);
      template<typename Visitor, typename Variant>
        typename Visitor::result_type apply_visitor(const Visitor &, Variant&&);
      template<typename BinaryVisitor, typename Variant1, typename Variant2>
        typename BinaryVisitor::result_type OR decltype(auto)
        apply_visitor(BinaryVisitor &, Variant1&&, Variant2&&);
      template<typename BinaryVisitor, typename Variant1, typename Variant2>
        typename BinaryVisitor::result_type OR decltype(auto)
        apply_visitor(const BinaryVisitor &, Variant1&&, Variant2&&);
      template<typename MultiVisitor, typename Variant1, typename Variant2,
               typename Variant3>
        typename MultiVisitor::result_type OR decltype(auto)
        apply_visitor(MultiVisitor &, Variant1&&, Variant2&&, Variant3&&, ...);
      template<typename MultiVisitor, typename Variant1, typename Variant2,
               typename Variant3>
        typename MultiVisitor::result_type OR decltype(auto)
        apply_visitor(const MultiVisitor &, Variant1&&, Variant2&&, Variant3&&,
                      ...);
      template<typename Visitor>
        apply_visitor_delayed_t<Visitor> apply_visitor(Visitor &);
      template<typename Visitor>
        apply_visitor_delayed_cpp14_t<Visitor> apply_visitor(Visitor &);
    }

### Header <boost/variant/multivisitors.hpp>

Provides declarations of apply_visitor for three or more `variant` parameters.

    BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS

    namespace boost {
      template<typename MultiVisitor, typename Variant1, typename Variant2,
               typename Variant3>
        typename MultiVisitor::result_type OR decltype(auto)
        apply_visitor /*three or more variant parameters*/(MultiVisitor &,
                                                           Variant1&&,
                                                           Variant2&&,
                                                           Variant3&&, ...);
      template<typename MultiVisitor, typename Variant1, typename Variant2,
               typename Variant3>
        typename MultiVisitor::result_type OR decltype(auto)
        apply_visitor /*three or more variant parameters*/(const MultiVisitor &,
                                                           Variant1&&,
                                                           Variant2&&,
                                                           Variant3&&, ...);
    }

### Header <boost/variant/get.hpp>

    namespace boost {
      class bad_get;
      template<typename U, typename T1, typename T2, ..., typename TN>
        U * relaxed_get(variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U * relaxed_get(const variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U & relaxed_get(variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U & relaxed_get(const variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U && relaxed_get(variant<T1, T2, ..., TN> &&);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U * strict_get(variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U * strict_get(const variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U & strict_get(variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U & strict_get(const variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U && strict_get(variant<T1, T2, ..., TN> &&);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U * get(variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U * get(const variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U & get(variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U & get(const variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U && get(variant<T1, T2, ..., TN> &&);
    }

### Header <boost/variant/polymorphic_get.hpp>

    namespace boost {
      class bad_polymorphic_get;
      template<typename U, typename T1, typename T2, ..., typename TN>
        U * polymorphic_relaxed_get(variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U * polymorphic_relaxed_get(const variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U & polymorphic_relaxed_get(variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U & polymorphic_relaxed_get(const variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U * polymorphic_strict_get(variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U * polymorphic_strict_get(const variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U & polymorphic_strict_get(variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U & polymorphic_strict_get(const variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U * polymorphic_get(variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U * polymorphic_get(const variant<T1, T2, ..., TN> *);
      template<typename U, typename T1, typename T2, ..., typename TN>
        U & polymorphic_get(variant<T1, T2, ..., TN> &);
      template<typename U, typename T1, typename T2, ..., typename TN>
        const U & polymorphic_get(const variant<T1, T2, ..., TN> &);
    }

### Header <boost/variant/bad_visit.hpp>

    namespace boost {
      class bad_visit;
    }

### Header <boost/variant/static_visitor.hpp>

    namespace boost {
      template<typename ResultType> class static_visitor;
    }

### Header <boost/variant/visitor_ptr.hpp>

    namespace boost {
      template<typename T, typename R> class visitor_ptr_t;
      template<typename R, typename T> visitor_ptr_t<T,R> visitor_ptr(R (*)(T));
    }