使用 Boost 反序列化 Armadillo colvec

Posted

技术标签:

【中文标题】使用 Boost 反序列化 Armadillo colvec【英文标题】:De-serialize Armadillo colvec with Boost 【发布时间】:2017-06-30 20:00:45 【问题描述】:

我正在尝试使用 Boost 序列化/反序列化 Armadillo colvec 对象。 colvec 是具有几个不同大小的列向量,例如它可以有 2 行用于 2d 向量,3 行用于 3d 向量,我还在代码中使用其他特定的向量大小。

当反序列化期间colvec中的行数未知时,我不确定如何处理boost中colvec类型的序列化。

例如要序列化,我可能包括以下内容:-

namespace boost

    namespace serialization
    
        template<class Archive>
        void serialize(Archive& archive, colvec& vector, unsigned int)
        
            for (int i=0; i<vector.size(); i++)
            
                archive& vector[i];
            
        
    

这将序列化具有任意行数的 colvec。但是,当此代码在“反序列化”期间运行时,向量将是 size()==0 的 colvec,例如所需的行数将是未知的。

我想知道处理这个问题的最佳方法是什么。

我的理解可能有误。我对犰狳和 Boost 都是新手。

【问题讨论】:

是的,抱歉,colvec 是 Mat 类的 Armadillo typedef。在这个例子中我没有使用 std::vector ... 什么是colvec? arma::Col? 是的,它是从 Mat 派生的 Col 的 typedef。 问题似乎是(尽管我可能会遗漏一些东西)是 Boost Serialization 将调用 colvec 的默认构造函数,这将生成一个具有 1 列的 Mat 结构。似乎默认构造函数不会为 colvec 创建行,因此它在反序列化期间显示为具有 1 列和 0 行的 Mat。因此反序列化失败。 【参考方案1】:

我建议分开加载/保存。对于数组,您还需要先存储大小,以便能够知道在反序列化时需要读取多少个组件。对于连续的内存布局,使用优化的

boost::serialization::make_array(T*,size)

功能。最后,如果你想支持 XML 归档使用

boost::serialization::make_nvp(char*, T)
// or the BOOST_SERIALIZATION_NVP macro

你可以看看

/usr/include/boost/serialization/vector.hpp

看Boost如何序列化std::vector,代码通俗易懂。

我从未使用过 Armadillo,但未优化的代码(我不知道内存布局等...)肯定会接近:

template<class Archive>
inline void save(Archive & ar,const colvec& v,const unsigned int) 

    const size_t size = v.size();
    ar << BOOST_SERIALIZATION_NVP(size);

    for(size_t i=0;i<size;++i) 
        ar << boost::serialization::make_nvp("v_i",v[i]);
    


template<class Archive>
inline void load(Archive & ar,colvec& v,const unsigned int) 

   size_t size;
   ar >> BOOST_SERIALIZATION_NVP(size);

   v.resize(size);

   for(size_t i=0;i<size;++i) 
        ar >> boost::serialization::make_nvp("v_i",v[i]);
    


template<class Archive>
inline void serialize(Archive & ar,colvec& v,
                      const unsigned int file_version) 

 boost::serialization::split_free(ar, v, file_version);


【讨论】:

也看看boost.org/doc/libs/1_64_0/libs/serialization/doc/… 谢谢。这是完美的,无需修改即可工作。我能想到的唯一另一种方法是将 colvec 包装在一个结构中,例如拥有一个结构“colvec2d”和另一个结构“colvec3d”等,并为每个结构创建不同的序列化方法。但这会很丑陋并且涉及大量代码更改。非常感谢您的出色回答。

以上是关于使用 Boost 反序列化 Armadillo colvec的主要内容,如果未能解决你的问题,请参考以下文章

c ++ boost将char数组反序列化为obj

如何使用 boost std::vector of boost::unordered_map 进行序列化/反序列化

使用Boost将派生类部分反序列化为基类时输入流错误

使用Armadillo和boost :: numeric :: odeint进行模板实例化

Boost反序列化错误

Armadillo 与 Boost Odeint 冲突:Odeint 在积分期间将状态向量的大小调整为零