Serialize optional<T> for T's that have no default constructor#352
Merged
gennaroprota merged 1 commit intoJul 22, 2026
Merged
Conversation
The value of an `optional<T>` is now handled like a single element of a standard library container: when `T` is default constructible, it is serialized in place, exactly as before; otherwise, construction is routed through `save_construct_data`/`load_construct_data` so that `T` can be reconstructed on load. This lets `optional<T>` be serialized for types that cannot or should not provide a default constructor (const-qualified members, third party classes, and so on). The default-constructible path is left byte for byte unchanged, so archives written by earlier versions keep the same layout. The construct-data path writes an extra `item_version` plus whatever `save_construct_data` emits, which is new wire content only for types that previously could not be serialized at all, so no existing archive is affected. Loading reconstructs the value with `detail::stack_construct`, which placement-constructs the object through `load_construct_data` before the value is read. This is unlike the pre-2017 implementation, which serialized into unconstructed storage (`detail::stack_allocate`), so the reliability concern that motivated the earlier restriction does not apply here. Closes issue #121.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The value of an
optional<T>is now handled like a single element of a standard library container: whenTis default constructible, it is serialized in place, exactly as before; otherwise, construction is routed throughsave_construct_data/load_construct_dataso thatTcan be reconstructed on load. This letsoptional<T>be serialized for types that cannot or should not provide a default constructor (const-qualified members, third party classes, and so on).The default-constructible path is left byte for byte unchanged, so archives written by earlier versions keep the same layout. The construct-data path writes an extra
item_versionplus whateversave_construct_dataemits, which is new wire content only for types that previously could not be serialized at all, so no existing archive is affected.Loading reconstructs the value with
detail::stack_construct, which placement-constructs the object throughload_construct_databefore the value is read. This is unlike the pre-2017 implementation, which serialized into unconstructed storage (detail::stack_allocate), so the reliability concern that motivated the earlier restriction does not apply here.Closes issue #121.