代码之家  ›  专栏  ›  技术社区  ›  Jayen

序列化变量映射

  •  9
  • Jayen  · 技术社区  · 14 年前

    如何序列化/反序列化boost::program_options::variables_map?我找不到已经实现的序列化函数,也不知道变量映射中可以使用哪些函数来提取和重新组装映射。

    1 回复  |  直到 12 年前
        1
  •  10
  •   rhashimoto    12 年前

    你好像发现了 boost::program_options::variables_map std::map 因此可以使用它的序列化(但请参阅后面的警告)。如果唯一剩下的问题是序列化 boost::any 它包含的值,那么你就快到了。

    boost::任意 值总是一个字符串或一个int,那么类似的东西应该可以工作。

    boost::任意 ):

    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::任意 ):

    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

    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::任意 bool 参数有问题(您可能需要序列化 布尔 variables_map 只要选一个 引用和反序列化。反序列化为真实的 标准::地图 变量映射 内容。