関数ポインタはシリアライズできるのであろうか?
/*
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;
}
}