Opened 7 years ago
Closed 7 years ago
#11343 closed Feature Requests (fixed)
load/save_construct_data not enough to serialize some containers of UDT
Reported by: | Owned by: | Robert Ramey | |
---|---|---|---|
Milestone: | To Be Determined | Component: | serialization |
Version: | Boost 1.58.0 | Severity: | Problem |
Keywords: | Cc: |
Description
In reference to this answer on SO http://stackoverflow.com/a/30437785/85371
(De)serializing a map with a non-default-constructible mapped type of Foo
fails to compile, even if save_construct_data
and load_construct_data
have been overloaded for this type.
*Note:* Part of this seems related to the (version of the) standard library implementation in use (see the linked SO post)
One can get around this by overloading for the std::pair<K const, Foo>
type that is _actually_ the element type for e.g. std::map<K, Foo>
, e.g. for the specific Foo
sample:
template <class Archive, typename K> inline friend void save_construct_data(Archive& ar, std::pair<K, Foo> const* v, const unsigned int) { ar & boost::serialization::make_nvp("first", v->first); ar & boost::serialization::make_nvp("second", v->second.i); } template <class Archive, typename K> inline friend void load_construct_data(Archive& ar, std::pair<K, Foo>* v, const unsigned int) { typename std::remove_cv<K>::type first; ar & boost::serialization::make_nvp("first", first); int tmp; ar & boost::serialization::make_nvp("second", tmp); new(v) std::pair<K, Foo>(first, tmp); }
However, this is not transparant (people have to provide different load/save_construct_data
overloads depending on which containers are going to contain their type) and it's repetitive work, which is also hard to get right.
A better, general, solution would be to do the load/save_construct_data trick generically for non-default-constructible types in the boost::serialization namespace. That way, people won't have to "know" about the std::pair<> implementation detail. They could just implement load/save_construct_data for their own user-types and it would JustWork™ whether they put it in a vector or a map.
Implementing that generically is less-than-trivial though, and might interfere with some other machineries internal to the Boost Serialization framework.
I'll prefer to get some help of the Boost Serialization maintainers to do that in a reliable way. So, it seems I'll be submitting two tickets today.
The fix for this has been checked into the develop and master branch and will appear in the next release. If you can't wait for that, you can clone/download the latest versions from github.