コードをテストしましたが、コンパイルしようとしても機能しませんでした。ただし、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 の Matrix パラメーターのテンプレート パラメーターが含まれています。これにより、コンパイル時または実行時のサイズに関係なく、すべてのタイプの行列とベクトルで動作できるようになります。これは、上記のコードに対する主要な機能強化です。
シリアライゼーション コードを個別の保存関数と読み込み関数に分割することが不可欠です。それ以外の場合、逆シリアル化コードは元のデータを保持するためにマトリックスのサイズを変更しません。Boost::Serialize は、シリアライゼーションまたはデシリアライゼーションで操作を実行するためにオーバーロードできるいくつかの追加機能を提供すると思いますが、このアプローチは実装が簡単でした。
メソッドのconst修飾子save
は必須です。あいまいなg ++エラーがこれにつながる前に、これが私のトラブルの原因でした。
このコードのストレス テストを完全に行ったとは言えません。あなた (または他の誰か) がこれ以上の問題を見つけた場合は、私に知らせてください。
それが役立つと信じてください。
シュムエル