Skip to main content

The JSON value type

json is one C++ type that behaves like several types at runtime — a tagged union with container semantics layered on top. Every operation on it starts by asking, implicitly or explicitly, "what kind of value is this right now?"

The value types

value_tJSON typeDefault C++ storage
nullnull(no payload)
booleantrue / falsebool
number_integernumberint64_t
number_unsignednumberuint64_t
number_floatnumberdouble
stringstringstd::string
arrayarraystd::vector<json>
objectobjectstd::map<std::string, json>
binary(no JSON equivalent)std::vector<uint8_t> with an optional subtype
discarded(parse failure marker)

number_integer, number_unsigned, and number_float are three distinct internal states even though JSON itself has only one number type — see Number handling and precision for how the parser picks between them.

The type state machine

A default-constructed json starts as null, and its type is decided the first time it's used — after that, most operations are only legal if they match the current type.

A null value is permissive — assigning a key into it turns it into an object, calling push_back on it turns it into an array — but once it has committed to a type, operations that only make sense for a different type throw type_error rather than silently coercing.

Inspecting the type

j.type() returns the value_t enum value directly; j.type_name() returns a short string ("object", "array", "number", …); and the is_*() family of predicates (is_object(), is_array(), is_number(), is_null(), and more specific variants like is_number_integer()) covers the common checks without needing the enum at all. See Type checking and conversions for the full predicate list and how they interact with extraction.

json vs ordered_json vs custom basic_json

jsonordered_jsoncustom basic_json
Key orderSorted (via std::map)Insertion orderWhatever ObjectType provides
Lookup costO(log n)O(n) (linear scan)Depends on ObjectType
When to reach for itDefault — machine-to-machine JSONHuman-diffable / order-sensitive outputCustom allocator, non-standard containers

See Custom allocators and JSON types for how basic_json's ten template parameters let you go further than ordered_json.

The binary value type

value_t::binary doesn't come from JSON text at all — plain JSON has no way to represent raw bytes — it only appears when round-tripping through a binary format like CBOR or MessagePack that supports a native byte-string type. See Binary formats for how it's produced and consumed.

See also