添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I have the same problem.
I have to decide now whether I go with std::variant in a new piece of code I'm writing right now for C++17 (so backward compatibility with older compilers is not an issue for this piece of code) or still use boost::variant. I found that the only dependency that keeps me from using std::variant all the way is the ability to boost::serialize it.

I can hack my own crude serialization for the specific variants I'm using, but I'm not enough of an MPL or template metaprogramming wizard to implement serialization of a generic variant.

So now the question is to use boost::variant or std::variant+"kludge", in the hope of being able to remove "kludge" some day - whether and when this day comes is the variable on which the decision depends.

Traditionally, we've implemented serialization for standard library types within the serialization libraries and for boost library types within the particular boost library. This is done in order to prevent the obligations of being the boost serialization library maintainer from growing beyond what I can do. As the standard library keeps importing more boost stuff and creating more stuff, it's hard to keep up with just the standard library.

For some reason long, long ago, I put serialization of boost::optional and boost::variant into the serialization library. Now that the standard has incorporated their own versions of these libraries things could get pretty confusing. So what I believe that the current implementations of variant and optional should be moved to their own boost/variant and boost/optional libraries and new versions for the std::variant and std::optional should be placed in the boost serialization library.

Make the move is not too difficult. But even that is a pain. The tests should be moved as well.

But then there is the question of implementation of the new libraries. One could start modifying the current implementations for boost. But I'm pretty sure their would be more. The Committee likes to take a boost library and "improve" it so that it's only mostly compatible. Also, the implementations could make use of more recent versions of C++. In particular the implementation of boost::variant supports MSVC going back to version 6.0 - very, very, old. I'm sure implementation could be better today. Of course this means tweaking the test Jamfile so that the tests for these libraries are run only for more recent compilers.

So this seemingly trivial task turns into the usual can of worms. I don't know when I'll get to it. If anyone want's to do it, I recommend that he:

a) fork the library
b) add your implementation to the code
c) update the documentation
d) add a test of serialization

create a pull request.

What's in it for you?

a) you get the enhancement to the library that you need.
b) you get can put your name on the copyright of the serialization code and the test and a note in the documentation.
c) so you can proudly wear the title of official boost library maintainer - which can look good on your resume,
d) the eternal gratitude of those who come after you.

Any update. I am using C++17 structures. We use boost::serialization, but it is getting less easy to use due to lack of support for more modern standard containers like the ones above. C++17 was 2 years ago. Still not supported. Soon we have to look for replacements as it is a lot of overhead to hack support into.

For anyone looking for a quick workaround for serializing std::variant (std::optional should be conceptually the same), this works for me:

namespace boost
	namespace serialization
		template <class Archive, typename ...Ts>
		void save(Archive& ar, const std::variant<Ts...>& obj, const unsigned int version)
			boost::variant<Ts...> v;
			std::visit([&](const auto& arg) {
				v = arg; 
			}, obj);
			ar & v;
		template <class Archive, typename ...Ts>
		void load(Archive& ar, std::variant<Ts...>& obj, const unsigned int version)
			boost::variant<Ts...> v;
			ar& v;
			boost::apply_visitor([&](auto& arg) {
				obj = arg;
			}, v);
		template <class Archive, typename ...Ts>
		void serialize(Archive& ar, std::variant<Ts...>& t, const unsigned int file_version)
			split_free(ar, t, file_version);

However please note that it still may not work as there is some bug with tracking memory for boost::variant #203 .
I serialize variants with PODs, so I overrode the header boost/serialization/variant.hpp line
typedef mpl::int_< ::boost::serialization::track_always> type;
typedef mpl::int_< ::boost::serialization::track_never> type;

and now I have correctly serialized std::variant with pod types. I don't know whether it will work for objects that need tracking