Boost.Serialization 研究(2)

公開:2006-01-18 06:27
更新:2020-02-15 04:36
カテゴリ:boost,windows,c++

関数ポインタはシリアライズできるのであろうか?


/*
Serializeの研究
課題:関数ポインタはシリアライズできるか?
結果:
できない。STATIC_ASSERTが出る。
C:\Boost\include\boost-1_33_1\boost\archive\detail\oserializer.hpp(316)
: error
C2027: 認識できない型 'boost::STATIC_ASSERTION_FAILURE<x>' が使われています。
上記エラー元をチェックするとこう書いてある。
// check that we're not trying to serialize something that
// has been marked not to be serialized.  If this your program
// traps here, you've tried to serialize a class whose trait
// has been marked "non-serializable". Either reset the trait
// (see level.hpp) or change program not to serialize items of this class
要するに、
・non-serializableな型をシリアライズするときにおきる。
・回避するには特性(traits)を取り除くか、対象クラスをシリアライズしないように
プログラムを変更せよ。
である。
さて、どうしたものか。
*/
#include <iostream>
#include <fstream>
#include <string>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/nvp.hpp>
//using namespace std;
struct a {
  friend class boost::serialization::access;
  typedef std::string& (a::*func_type)();
  a() : m_str("") {}
  a(std::string& str) : m_str(str){}
  std::string& str(){return m_str;}
private:
  std::string m_str;
  template<class Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & BOOST_SERIALIZATION_NVP(m_str);
  }
};
struct b {
  friend class boost::serialization::access;
  b(){ma = new a();}
  b(std::string& s) {
    ma = new a(s);
    m_func_ptr = &a::str;
  }
  ~b(){delete ma;}
  a* pa(){return ma;};
  const std::string& str(){return (ma->*m_func_ptr)();}
private:
  a* ma;
  a::func_type m_func_ptr;
  template<class Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & BOOST_SERIALIZATION_NVP(ma);
    ar & BOOST_SERIALIZATION_NVP(m_func_ptr);
  }
};
struct c {
  friend class boost::serialization::access;
  c() {};
  c(a* v){ma = v;};
  ~c(){}
  a* pa() {return ma;};
private:
  template<class Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & BOOST_SERIALIZATION_NVP(ma);
  }
  a* ma;
};
int main()
{
  {   // シリアライズ
    std::string s_ = "def";
    b b_(s_);
    c c_(b_.pa());
    std::ofstream ofs("output.xml");
    boost::archive::xml_oarchive oa(ofs);
    // わざと逆順に保存
    oa & BOOST_SERIALIZATION_NVP(c_);
    oa & BOOST_SERIALIZATION_NVP(b_);
  }
  {   // 再構築
    b b_;
    c c_;
    std::ifstream ofs("output.xml");
    boost::archive::xml_iarchive oa(ofs);
    oa & BOOST_SERIALIZATION_NVP(c_);
    oa & BOOST_SERIALIZATION_NVP(b_);
    //
    std::cout << "b: string member is " << b_.str() << std::endl;
    std::cout << "c: string member is " << c_.pa()->str() << std::endl;
  }
}