【发布时间】:2025-12-19 10:10:12
【问题描述】:
我使用 boost::serialization 并且非常喜欢它。我有时会想念的唯一一件事是,当我想从 xml 存档中读取配置输入结构时。那就太好了,如果
- xml 结构可以是顺序无关的,并且
- 如果 xml 中缺少对象,将采用类的默认值。
这主要是用于 boost::serialization 还是您已经有解决方案?
【问题讨论】:
标签: c++ xml boost boost-serialization
我使用 boost::serialization 并且非常喜欢它。我有时会想念的唯一一件事是,当我想从 xml 存档中读取配置输入结构时。那就太好了,如果
这主要是用于 boost::serialization 还是您已经有解决方案?
【问题讨论】:
标签: c++ xml boost boost-serialization
因为我认为show-don't-tell 更有建设性,以下是我认为您在使用 Boost Property Tree 之后的示例:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
struct Config {
std::string order;
double independent;
std::string stuff;
static Config load_xml(std::istream& from) {
boost::property_tree::ptree pt;
read_xml(from, pt);
return {
pt.get("order", "default property value for order"),
pt.get("independent", 42.0),
pt.get("stuff", "no stuff configured")
};
}
void save_xml(std::ostream& to) const {
boost::property_tree::ptree pt;
if (!order.empty()) pt.put("order", order);
if (independent != 0) pt.put("independent", independent);
if (!stuff.empty()) pt.put("stuff", stuff);
write_xml(to, pt);
}
};
#include <iostream>
int main() {
{
Config cfg { "order", 999, "stuff" };
cfg.save_xml(std::cout);
}
std::istringstream iss("<independent>3.1415926535897931</independent><IGNORED>stuff</IGNORED><order>LOOK MA</order>");
Config::load_xml(iss).save_xml(std::cout);
}
哪些打印:
<?xml version="1.0" encoding="utf-8"?>
<order>order</order><independent>999</independent><stuff>stuff</stuff>
<?xml version="1.0" encoding="utf-8"?>
<order>LOOK MA</order><independent>3.1415926535897931</independent><stuff>no stuff configured</stuff>
【讨论】:
序列化不是为了这个。
当然你可以让你序列化的东西与顺序无关:
#include <boost/serialization/map.hpp>
struct MyConfig {
std::map<std::string, std::string> values;
template<typename Ar> void serialize(Ar& ar, unsigned) {
ar & values;
}
};
阅读的顺序无关紧要。
此外,您已经可以使用可选的默认值(提示:它与序列化完全无关):
struct MyConfig {
std::string const& workingDirectory() {
return *values.emplace("workingdir", "$HOME").first;
}
private:
std::unordered_map<std::string, std::string> values;
};
这里workingDirectory() 将返回对反序列化值的引用。如果不存在这样的值,则会先插入"$HOME"。
对于这种情况,您应该考虑使用Boost Property Tree。它更适合这个目的。
【讨论】:
std::map<std::string, boost::variant<std::string, double, bool, ...> >?