Boost C++ Libraries of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards


Value Conversion

While the value container makes it easy to create ad-hoc structures, often it is necessary to convert between JSON and user-defined types or types from the standard library.

The function template value_from provides an interface to construct a value from a type T. The function template value_to converts in the opposite direction, from a type T to value. Both support a wide variety of different fundamental types, such as int or double, standard library types, such as std::string or std::vector<T>, and can be extended to support user-defined types.

std::vector< int > v1{ 1, 2, 3, 4 };

// Convert the vector to a JSON array
value jv = value_from( v1 );
assert( serialize( jv ) == R"([1,2,3,4])" );

// Convert back to vector< int >
std::vector< int > v2 = value_to< std::vector< int > >( jv );
assert( v1 == v2 );

For the type T, the appropriate conversion approach is chosen from the following list of categories. The first matching category is selected.

Table 1.3. Conversion categories

Category of T


value_from behavior

value_to behavior

Custom conversion

Custom behavior.

Custom behavior.

Boost.JSON container

The result is equal to the input value.

The result is equal to the input value.


The result is equal to the input value.

The result is equal to the input value.

Arithmetic type

The result is a number equal to input and has the type

* std::int64_t, if T is a signed integer'; or

* std::uint64_t, if T is an unsigned integer; or

* double otherwise.

The result is created via value::to_number.

Type satisfying is_null_like

Intended for types like std::monostate.

The result is a null value.

The result is default-constructed.

Type satisfying is_string_like

A sequence of chars, e.g. std::string.

The result is a string.

The result is constructed from a string_view.

Type satisfying is_map_like

A one-to-one mapping (e.g. std::map) with string-like keys.

The result is an object.

The result is default-constructed, and elements are insert-ed at the end.

Type satisfying is_sequence_like

A sequence of elements, e.g. std::vector.

The result is an array.

The result is default-constructed, and elements are insert-ed at the end.

Type satisfying is_tuple_like

A heterogenous sequence with fixed size, e.g. std::tuple and std::pair.

The result is an array.

The result is constructed with the array elements as constructor arguments.

Type satisfying is_described_class

The result is an object with described members' names as keys.

The result is default-constructed and described members are assigned corresponding values.

Type satisfying is_described_enum

If the input value is equal to one of the described enumerators, the result is a string, containing its name. Otherwise it's equal to the input value converted to its underlying type.

The result is the described enumerator, corresponding to the input string.

Type satisfying is_variant_like

std::variant and similar types, e.g. boost::variant2::variant.

The result is equal to the result of conversion of the active variant alternative.

The result holds the first alternative for which a conversion succeeds.

Type satisfying is_optional_like

If the input value is empty, the result is a null. Otherwise it is equivalent to conversion of the object stored inside of optional.

The result is default constructed if the input value is null. Otherwise the result is constructed from the result of conversion of the input to the type stored in optional.

Type satisfying is_path_like

std::filesystem::path and similar types, e.g. boost::filesystem::path.

The result is equal to the result of path::generic_string.

The result is constructed from two pointers to const char.

For composite types (sequences, tuples, described classes, etc.) conversion of contained objects is applied recursively. For example:

std::map< std::string, std::pair<int, bool> > m = {
    {"a", {1, false}},
    {"b", {4, true}},
    {"c", {5, false}},

value jv = value_from( m );

assert(( jv == object{
    {"a", array{1, false}},
    {"b", array{4, true}},
    {"c", array{5, false}},

Here, the map is converted into an object, since it matches is_map_like. Each of its keys is converted into a string, as std::string matches is_string_like, and each of its values is converted into an array, as std::pair matches is_tuple_like. Finally, elements of pairs are converted into a std::int64_t number and a bool.