Boost C++ Libraries

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

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

Initializer Lists

Initializer lists can be used to construct or assign a value:

value jv = {
    { "name", "John Doe" },
    { "active", true },
    { "associated-accounts", nullptr },
    { "total-balance", 330.00 },
    { "account-balances", { 84, 120, 126 } } };

Simple initializer lists produce an array:

value jv = { true, 2, "hello", nullptr };

assert( jv.is_array() );

assert( jv.as_array().size() == 4 );

assert( serialize(jv) == "[true,2,\"hello\",null]" );

Initializer lists can be nested. Here we construct an array as an element of an array:

value jv = { true, 2, "hello", { "bye", nullptr, false } };

assert( jv.is_array() );

assert( jv.as_array().back().is_array() );

assert( serialize(jv) == "[true,2,\"hello\",[\"bye\",null,false]]" );

When a two element initializer list is nested within an enclosing initializer list, it is unclear whether it represents an array or an object:

// Should this be an array or an object?
value jv = { { "hello", 42 }, { "world", 43 } };

In such cases, if every element consists of a string followed by a single value, then the enclosing initializer list is interpreted as an object. Otherwise, it is interpreted as an array.

value jv1 = { { "hello", 42 }, { "world", 43 } };

assert( jv1.is_object() );

assert( jv1.as_object().size() == 2 );

assert( serialize(jv1) == R"({"hello":42,"world":43})" );

// All of the following are arrays

value jv2 = { { "make", "Tesla" }, { "model", 3 }, "black" };

value jv3 = { { "library", "JSON" }, { "Boost", "C++", "Fast", "JSON" } };

value jv4 = { { "color", "blue" }, { 1, "red" } };

assert( jv2.is_array() && jv3.is_array() && jv4.is_array() );

To resolve the ambiguity manually, use an explicit constructor:

value jv = { { "hello", 42 }, array{ "world", 43 } };

assert( jv.is_array() );

array& ja = jv.as_array();

assert( ja[0].is_array() && ja[1].is_array());

assert ( serialize(jv) == R"([["hello",42],["world",43]])" );

Initializer lists can be used to unambiguously construct or assign an object or array:

value jv = { { "mercury", 36 }, { "venus", 67 }, { "earth", 93 } };

assert( jv.is_object() );

assert( serialize(jv) == "{\"mercury\":36,\"venus\":67,\"earth\":93}" );

array ja = { { "mercury", 36 }, { "venus", 67 }, { "earth", 93 } };

assert( serialize(ja) == "[[\"mercury\",36],[\"venus\",67],[\"earth\",93]]" );

Similarly, an initializer list for an object is always interpreted as an object. In such cases, the initializer list must be a list of key-value pairs. For example, the following code will not compile because 1 is not convertible to a string:

object jo = { { 1, 0.39 }, { "venus", 0.72 }, { "earth", 1 } };

The requirement for an initializer list to be interpreted as an object or array when initializing such an entity only applies to the outermost initializer list; subsequent nested elements will follow the usual ambiguity resolution rules.

object jo = { { "mercury", { { "distance", 36 } } }, { "venus", { 67, "million miles" } }, { "earth", 93 } };

assert( jo["mercury"].is_object() );

assert( jo["venus"].is_array() );

Elements that are rvalues will be moved upon initialization:

object jo1 = { { "john", 100 }, { "dave", 500 }, { "joe", 300 } };

value jv = { { "clients", std::move(jo1) } };

object& jo2 = jv.as_object()["clients"].as_object();

assert( ! jo2.empty() && jo1.empty() );

assert( serialize(jv) == R"({"clients":{"john":100,"dave":500,"joe":300}})" );
[Warning] Warning

Do not create variables of type std::initializer_list. This may result in temporaries being destroyed before the initializer list is used.

In all cases, the storage_ptr owned by an object, array, or value constructed from an initializer list will be propagated to each element, recursively.


PrevUpHomeNext