如何序列化/反序列化 boost::program_options::variables_map?我找不到已经实现的序列化函数,而且我不知道 variables_map 中的哪些函数可以用来提取和重新组装 map 。
最佳答案
看起来你发现 boost::program_options::variables_map
派生自 std::map
所以你可以使用它的序列化(但稍后会看到警告这个)。如果剩下的唯一问题是序列化它包含的 boost::any
值,那么您就快完成了。
你不能序列化一个任意的 boost::any ,因为它不知道如何操纵它所拥有的东西。但是,如果您知道并且可以枚举您的应用程序使用的类型,那么序列化是可能的。例如,如果您知道 boost::any
值始终是一个字符串或一个 int,那么像这样的东西应该可以工作。
要序列化(值为 boost::any
):
if (value.type() == typeid(int)) {
ar << std::string("int");
ar << boost::any_cast<int>(value);
}
else if (value.type() == typeid(std::string)) {
ar << std::string("string");
ar << boost::any_cast<std::string>(value);
}
要反序列化(值为 boost::any
):
std::string type;
ar >> type;
if (type == "int") {
int x;
ar >> x;
value = x;
}
else if (type == "string") {
std::string x;
ar >> x;
value = x;
}
显然,您可以在序列化流中使用比“int”和“string”更有效的类型标签,但这为您提供了基本思路。
编辑:boost::archive
对 const 引用很挑剔,所以我上面写的东西不能完全编译。确实如此,并且它适用于非常简单的测试:
enum {
TYPE_int,
TYPE_string,
};
namespace boost {
namespace serialization {
template<class Archive>
void save(Archive& ar, const boost::program_options::variable_value& value, unsigned int version) {
const boost::any& anyValue = value.value();
if (anyValue.type() == typeid(int)) {
int type = static_cast<int>(TYPE_int);
int typedValue = boost::any_cast<int>(anyValue);
ar << type << typedValue;
}
else if (anyValue.type() == typeid(std::string)) {
int type = static_cast<int>(TYPE_string);
std::string typedValue = boost::any_cast<std::string>(anyValue);
ar << type << typedValue;
}
}
template<class Archive>
void load(Archive& ar, boost::program_options::variable_value& value, unsigned int version) {
boost::any anyValue;
int type;
ar >> type;
if (type == TYPE_int) {
int x;
ar >> x;
anyValue = x;
}
else if (type == TYPE_string) {
std::string x;
ar >> x;
anyValue = x;
}
value = boost::program_options::variable_value(anyValue, false);
}
template<class Archive>
void serialize(Archive& ar, boost::program_options::variables_map& value, unsigned int version) {
// Probably works but is sloppy and dangerous. Would be better to
// deserialize into a temporary std::map and build a variables_map
// properly. Left as an exercise.
ar & static_cast<std::map<std::string, boost::program_options::variable_value>&>(value);
}
}
}
BOOST_SERIALIZATION_SPLIT_FREE(boost::program_options::variable_value);
此代码可能存在几个问题。第一个是在 load()
中用于 variable_value
- 最后一个语句从 boost::any
生成一个 variable_value
而且我不太确定 bool
参数做了什么(您可能需要序列化 bool
代表的任何内容)。第二个是,您可能会或可能不会通过仅转换为 std::map
引用和反序列化来获得一致的 variables_map
。反序列化为真正的 std::map
然后从 std::map
内容构建 variables_map
会更安全。
关于c++ - 序列化 variables_map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4112116/