我已经测试了你的代码,当我尝试编译它时它也没有工作。但是,根据 Boost Serialize 的文档,我的印象是它旨在与流运算符
namespace boost {
namespace serialization {
template <class Archive, typename Derived>
void serialize( Archive & ar, Eigen::EigenBase<Derived> & g, const unsigned int version){
ar & boost::serialization::make_array(g.derived().data(), g.size());
}
}
}
int main (int argc, char* argv[]){
std::ofstream out("my_archive");
boost::archive::text_oarchive oa (out);
Eigen::Matrix <double, 4, 4> a;
out << a;
return 0;
}
文件 my_archive 是在工作文件夹中创建的,具有非零值(只是内存中未初始化的垃圾,上面的代码过于简化)。
编辑:
我尝试在我自己的应用程序中使用上面的确切代码,发现我收到了和你一样的错误。老实说,我现在不明白为什么会这样。我发现的最简单的解决方法是将Eigen::EigenBase<Derived> 替换为实际使用的 Matrix 类型。我正在使用的当前代码是:
namespace boost{
namespace serialization {
template <class Archive, typename Scalar>
void serialize ( Archive & ar, Eigen::Matrix<Scalar, -1, -1, 0, -1, -1> & g, const unsigned int version ){ /* ... */ }
}
}
上面的代码适用于任何标量类型(float、double、int)和动态/运行时大小的矩阵。对于静态大小,请检查并相应地更新模板参数。
编辑 #2(2014 年 4 月 9 日):
尽管上述代码看起来可以正常工作,但当我尝试将其完全集成到我的代码中并通过适当的单元测试对其进行练习时,它停止了工作。不幸的是,我收到的错误消息——来自 Visual Studio 和 clang——是最没有帮助的。幸运的是,gcc 隐藏在可怕的错误消息中,对 CV 不匹配的引用,这似乎让我能够完全解决这个问题。
以下代码现在似乎可以编译并成功运行。我试图使格式清晰(没有横向滚动)——希望下面的代码是清晰的:
namespace boost{
namespace serialization{
template< class Archive,
class S,
int Rows_,
int Cols_,
int Ops_,
int MaxRows_,
int MaxCols_>
inline void save(
Archive & ar,
const Eigen::Matrix<S, Rows_, Cols_, Ops_, MaxRows_, MaxCols_> & g,
const unsigned int version)
{
int rows = g.rows();
int cols = g.cols();
ar & rows;
ar & cols;
ar & boost::serialization::make_array(g.data(), rows * cols);
}
template< class Archive,
class S,
int Rows_,
int Cols_,
int Ops_,
int MaxRows_,
int MaxCols_>
inline void load(
Archive & ar,
Eigen::Matrix<S, Rows_, Cols_, Ops_, MaxRows_, MaxCols_> & g,
const unsigned int version)
{
int rows, cols;
ar & rows;
ar & cols;
g.resize(rows, cols);
ar & boost::serialization::make_array(g.data(), rows * cols);
}
template< class Archive,
class S,
int Rows_,
int Cols_,
int Ops_,
int MaxRows_,
int MaxCols_>
inline void serialize(
Archive & ar,
Eigen::Matrix<S, Rows_, Cols_, Ops_, MaxRows_, MaxCols_> & g,
const unsigned int version)
{
split_free(ar, g, version);
}
} // namespace serialization
} // namespace boost
上面代码的几个关键点:
此代码现在具有所有 Eigen 矩阵参数的模板化参数。这应该允许它与所有类型的矩阵和向量一起工作,无论是在编译时还是在运行时调整大小。这是对上述代码的重大改进
必须将序列化代码拆分为单独的 save 和 load 函数。否则,反序列化代码将不会调整矩阵大小以保存原始数据。我相信 Boost::Serialize 确实提供了一些额外的函数,这些函数可以被重载以执行序列化或反序列化的操作,但这种方法更容易实现。
save 方法上的 const 限定符是必不可少的。在一个不起眼的 g++ 错误让我陷入困境之前,这就是我麻烦的根源。
我不能说我已经对这段代码进行了全面的压力测试。如果您(或其他任何人)发现任何其他问题,请告诉我,我会尝试跟进我发现的任何其他问题。
相信这会有所帮助。
施穆尔