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: bugs@… 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.

Change History (1)

comment:1 by Robert Ramey, 7 years ago

Resolution: fixed
Status: newclosed

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.

Note: See TracTickets for help on using tickets.