From e4e76bf4267f55b5fa8d0edfc6495d7967f94098 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 14:22:43 +0000 Subject: [PATCH] docs: document std::pair/std::tuple serializing as an object for string-keyed pairs A std::pair or std::tuple whose every element is itself a two-element array with a string first element (e.g. std::pair) serializes to a JSON object instead of a JSON array, because to_json builds the value with a brace initializer and the initializer-list object-detection rule fires. The resulting object cannot be read back into the original type and collapses duplicate keys. Document this quirk in the conversions guide, together with the unaffected cases and the idiom to force an array. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_016cwQq8WQRFzQcGQtbJTtJg Signed-off-by: Claude --- docs/mkdocs/docs/features/conversions.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/mkdocs/docs/features/conversions.md b/docs/mkdocs/docs/features/conversions.md index 765c610ab..94a660ec8 100644 --- a/docs/mkdocs/docs/features/conversions.md +++ b/docs/mkdocs/docs/features/conversions.md @@ -54,6 +54,30 @@ json j = {1.0, "hello", 42}; auto t = j.get>(); // {1.0, "hello", 42} ``` +!!! warning "Serializing a `std::pair`/`std::tuple` whose every element is a string-keyed pair" + + When *every* element of a `#!cpp std::pair` or `#!cpp std::tuple` is itself a two-element array whose first + element is a string (for example `#!cpp std::pair`), serializing it produces a JSON **object** + instead of the expected array: + + ```cpp + using kv = std::pair; + json j = std::pair{{"a", 1}, {"b", 2}}; // {"a":1,"b":2}, not [["a",1],["b",2]] + ``` + + This is a consequence of the [brace-initializer object-detection rule](creating_values.md): the same rule that + lets `#!cpp json{{"a", 1}, {"b", 2}}` create an object also fires here. The resulting object cannot be read back + into the original type (`#!cpp get>()` throws [`type_error.302`](../home/exceptions.md#jsonexceptiontype_error302)), + and duplicate keys collapse into one, losing elements. This only affects `#!cpp std::pair`/`#!cpp std::tuple` + themselves; a `#!cpp std::vector>`, or a pair/tuple with at least one element that is + not a string-keyed pair, serializes to an array as expected. To force an array, build one explicitly from the + elements with [`array`](../api/basic_json/array.md): + + ```cpp + std::pair p{{"a", 1}, {"b", 2}}; + json a = json::array({p.first, p.second}); // [["a",1],["b",2]] + ``` + !!! info "Extracting references into a tuple" A tuple type may also hold references (e.g. `#!cpp std::tuple`) to avoid copying: `get`