Skip to content

Conversation

@KJTsanaktsidis
Copy link

If a type has a private no-args constructor, but has friended boost::serialization::access, it can usually be deserialised as normal. However, it can't be deserialized out of a variant, because the variant tries to invoke the default constructor.

Fix this by constructing it through boost::serialization::access, which is designed to model "classes that can't be created with no arguments except through deserialization"

If a type has a private no-args constructor, but has friended
boost::serialization::access, it can usually be deserialised as normal.
However, it _can't_ be deserialized out of a variant, because the
variant tries to invoke the default constructor.

Fix this by constructing it through boost::serialization::access, which
is designed to model "classes that can't be created with no arguments
except through deserialization"
@KJTsanaktsidis KJTsanaktsidis force-pushed the kjtsanaktsidis/fix_private_variant branch from 08a83d5 to 860d977 Compare February 6, 2026 08:54
::new(t)T;
}
template<class T>
static T *construct_r(void * t) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, had to add a new overload of construct that actually returned the placement-new result, because of pointer provenance issues.

alignas(T) unsigned char mem[sizeof(T)];
T *ptr = reinterpret_cast<T*>(mem);
::new(ptr)T;

ptr->stuff();

Apparently is no bueno because the compiler can assume that ptr is NOT the same thing as the in-place-constructed T. Need to instead do something like

alignas(T) unsigned char mem[sizeof(T)];
T *ptr = ::new(mem)T;

ptr->stuff();

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.

1 participant