用于增强序列化的与顺序无关的输入存档

Order-independent input archive for boost serialization

我用boost::serialization,非常喜欢。我有时会想念的唯一一件事是当我想从 xml 存档中读取配置输入结构时。那就太好了,if

  1. xml 结构可以与顺序无关并且
  2. 如果 xml 中缺少对象,将采用 class 的默认值。

这主要适用于 boost::serialization 还是您已经有解决方案?

序列化不是为了这个。

当然你可以让你序列化的东西无论如何都与顺序无关:

#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() 将 return 对反序列化值的引用。如果不存在这样的值,将首先插入 "$HOME"

然而

您应该考虑在这种情况下使用 Boost Property Tree。它更适合这个目的。

因为我认为展示而不是讲述更有建设性,下面是我认为您在使用 Boost 后的示例 属性 树:

Live On Coliru

#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>

here 是我的实验性 boost::serialization 存档,它能够序列化为 boost::property_tree.

默认情况下,生成的 ptree 是以适合 json 或信息格式的方式创建的,但只需稍作修改即可针对 xml.

进行优化

它可以按任意顺序加载字段,也可以忽略其他字段(这允许一些向前兼容)。

当前错过的字段将产生错误。引入具有默认值的可选字段需要一些额外的工作。

还有一个 patch for xml archive 允许跳过未知字段,但它不允许任意顺序或可选字段。