BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_variant

Typedefs

typedef void BSLSTL_VARIANT_NOT_A_TYPE
 

Detailed Description

Outline

Purpose

Provide a standard-compliant allocator aware variant type.

Classes

Canonical header: bsl_variant.h

Description

This component provides a class template, bsl::variant<TYPES...>, that is a not-yet-standardised allocator-aware version of std::variant. For functionality common to std::variant, C++23 was used as the reference specification, modulo limitations listed below. bsl::variant may hold and manage the lifetime of an object, known as the contained value, which is stored within the footprint of the bsl::variant object, and must be one of the template arguments TYPES. These template arguments are called alternatives, and the alternative corresponding to the contained value is said to be active. A bsl::variant object may also hold no value under exceptional circumstances.

A program that instantiates the definition of variant with no template arguments is ill-formed.

A reference or pointer to the contained value of a bsl::variant can be obtained using the free functions get or get_if, respectively. Such a reference or pointer that does not have top-level const may be used to modify the contained value directly, if desired.

bsl::variant is copy/move constructible when all alternatives are copy/move constructible; the resulting object holds the alternative that the source object held. bsl::variant can also be constructed from a value of one of the alternatives, or from an expression for which there is an unambiguous best match conversion to one of the alternatives. In addition, bsl::variant supports construction of an explicitly specified alternative from a variadic number of arguments.

If at least one alternative is allocator-aware, bsl::variant is allocator-aware. For an allocator-aware bsl::variant, each constructor has a matching allocator-extended version that specifies the allocator that will be used during the lifetime of the bsl::variant object to construct any allocator-aware alternative that the bsl::variant object holds. Note that the bsl::variant object itself does not allocate any memory; its footprint is large enough to hold any of its alternatives.

bsl::variant is copy/move assignable when all alternatives are copy/move assignable and copy/move constructible; if the LHS has a different active alternative than the RHS, the contained value of the LHS will be destroyed before the contained value of the new alternative is created. bsl::variant may also be assigned to from an expression for which there is an unambiguous best match conversion to one of the alternatives.

The bsl::variant::emplace methods, which take an explicitly specified alternative, can also be used to construct a contained value after a bsl::variant object has already been constructed. If the bsl::variant object already holds a contained value, that object will be destroyed before the specified alternative is created.

If an exception is thrown during an operation that changes the active alternative in a bsl::variant object, the bsl::variant object might be left in a state that holds no value, referred to as the valueless by exception state, indicated by the valueless_by_exception() method returning true and the index() method returning bsl::variant_npos.

Two bsl::variants of the same type compare equal if they hold the same alternative and their contained values compare equal, or they both hold no value.

The index() method returns the zero-based index of the current alternative. Additionally, the free function holds_alternative can be used to check whether an explicitly specified type is the currently active alternative.

Free function bsl::visit is provided that implements the visitor design pattern as specified by the C++ standard, modulo limitations listed below.

Usage

This section illustrates intended use of this component.

Example 1: Basic Variant Use

First, we create a variant object that can hold an integer, a char, or a string. The default constructor of bsl::variant<TYPES...> creates the first alternative in TYPES...; to create a different alternative, we can provide the index or the type of the alternative to create:

assert(bsl::holds_alternative<int>(v1));
assert(bsl::holds_alternative<char>(v2));
Definition bslstl_variant.h:3685
Definition bslstl_inplace.h:137

Next, we create a visitor that can be called with a value of any of the alternatives:

class MyVisitor {
public:
template <class t_TYPE>
void operator()(const t_TYPE& value) const
{
bsl::cout << value << bsl::endl;
}
};

We can now use bsl::visit to apply the visitor to our variant objects:

MyVisitor visitor;
bsl::visit(visitor, v1); // prints integer 0
bsl::visit(visitor, v2); // prints char 'c'
bsl::invoke_result< t_VISITOR &, typenamebsl::variant_alternative< 0, t_VARIANT >::type & >::type visit(t_VISITOR &visitor, t_VARIANT &variant)
Definition bslstl_variant.h:2262

To retrieve a contained value, we can use the get free functions. If the requested alternative is not the currently active alternative, an exception of type bsl::bad_variant_access will be thrown.

assert(0 == bsl::get<int>(v1));
assert('c' == bsl::get<1>(v2));
try {
bsl::get<int>(v2);
} catch (const bsl::bad_variant_access& ex) {
bsl::cout << "non-active alternative requested" << bsl::endl;
}

Example 2: Variant Default Construction

Suppose we want to default construct a bsl::variant which can hold an alternative of type S. Type S is not default constructible so we use bsl::monostateas the first alternative to allow for default construction of the variant object.

struct S {
S(int i) : d_i(i) {}
int d_i;
};

To create an alternative of type S. we can use the emplace method.

v3.emplace<S>(3);
assert(bsl::holds_alternative<S>(v3));
bsl::enable_if< BloombergLP::bslstl::Variant_HasUniqueType< t_TYPE, variant >::value, t_TYPE & >::type emplace()
Definition bslstl_variant.h:8539

Known limitations

Typedef Documentation

◆ BSLSTL_VARIANT_NOT_A_TYPE