Skip to content

fix(cpp): support std::optional in Utf16_Utf8 string conversion#2981

Merged
schani merged 1 commit into
masterfrom
agent/fix-issue-2383
Jul 20, 2026
Merged

fix(cpp): support std::optional in Utf16_Utf8 string conversion#2981
schani merged 1 commit into
masterfrom
agent/fix-issue-2383

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Bug

With --wstring use-wstring --no-boost (the C++17 std::optional code path) and an optional string property, the generated C++ fails to compile:

testy2.h: In instantiation of 'static toType quicktype::Utf16_Utf8<fromType, toType>::convert(fromType) [with fromType = std::optional<std::string>; toType = std::optional<std::wstring>]':
testy2.h:165:94:   required from here
testy2.h:98:62: error: could not convert '...convert(...)' from 'optional<basic_string<char>>' to 'optional<basic_string<wchar_t>>'

Root cause

The generated Utf16_Utf8 helper class (emitted in emitHelperFunctions, packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts) only had convert overloads for std::shared_ptr, std::vector, and std::map. There was no overload for std::optional/boost::optional, so calls on optional string properties fell through to the generic fallback overload, which just returns the value unchanged — producing a type mismatch the compiler rejects.

Fix

Added a recursive convert overload for the configured optional type (std::optional or boost::optional, matching the --wstring/--no-boost renderer options) to Utf16_Utf8, mirroring the existing shared_ptr overload. It's only emitted when the generated code actually has optional properties (haveOptionalProperties), matching how other optional-only helper code is conditionally emitted elsewhere in this renderer.

Test coverage

Pinned the existing C++ wstring: use-wstring quicktest renderer option to test/inputs/json/priority/bug2521.json, which contains an optional string property (foo present on only one array element). This exercises the Utf16_Utf8<std::optional<...>>::convert path at compile time for the use-wstring code path, previously it ran against unpinned default quicktest inputs that didn't hit this combination.

Verification

  • Confirmed the bug on unfixed master using the repro from the issue/triage comment (schema2.json + --wstring use-wstring --no-boost ...): g++ 13.3 -std=c++17 fails with the exact error quoted above.
  • After the fix, regenerated the same repro and compiled with g++ -std=c++17 -I. -c main2.cpp — compiles cleanly.
  • Generated C++ for bug2521.json with --wstring use-wstring, built it against the real test/fixtures/cplusplus driver (main.cpp/json.hpp) with g++ -O0 -std=c++17 — compiles and runs successfully (previously this exact combination is what the pinned quicktest now exercises in CI).
  • npm run build passes.
  • npm run test:unit — 163/163 tests pass.
  • Ran QUICKTEST=true FIXTURE=cplusplus script/test locally; it hit an unrelated, pre-existing environment gap (this sandbox has no libboost-dev, so the pre-existing ["pokedex.json", { boost: "true" }] quicktest fails with boost/optional.hpp: No such file or directory before reaching later quicktests) — this is unrelated to this change and will run fully in CI, which has boost available.

Fixes #2383

🤖 Generated with Claude Code

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
@schani
schani merged commit 35f131a into master Jul 20, 2026
28 checks passed
@schani
schani deleted the agent/fix-issue-2383 branch July 20, 2026 21:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C++ Error : cannot convert from 'fromType' to 'std::optional<std::string>

1 participant