ユーザ定義のクラステンプレートに対してBoost.Seriazation用のversioningを行う

#include <boost/serialization/version.hpp>

namespace My{

template<class T>
class MyClass
{
  .....
};

} // namespace My

namespace boost{ namespace serialization{

template<class T>
struct version<My::MyClass<T> >
{
  BOOST_STATIC_CONSTANT(unsigned int, value = 2); // versionを2に指定する
};

}} // namespace boost::serialization

クラステンプレートだとBOOST_CLASS_VERSIONマクロが使えないことに対する回避策.
一見するとboost::serializationに侵入した危険なコードに見えますが,boost::serialization::versionのようなクラスは型特性(type traits)クラスとして提供されているもので,このようなユーザ定義クラスに対して侵入的に特殊化することは極めて妥当な使い方(というかこういう使い方のために存在するのが型特性クラス)です.std名前空間内のクラステンプレート,関数テンプレートについても基本的にこういう侵入的な特殊化が許されています.(参考:http://d.hatena.ne.jp/Cryolite/01000227

メモリ内Serialization

どうしても(PODであるかどうかといった)何らの仮定もおけない型を型安全じゃない形(バイナリ)でメモリ上に記録する必要があって,そうなるとどうしても環境を変えた際の危険性が付きまとう.Serialization + αでそういう部分をある程度安全かつ汎用に扱う方法がないかとちょっと模索していたんだけれど,string_stream + binary_[i|o]archiveっつー方法があるじゃん♪ということにさっき気が付いた.
というか今までstring_stream = in-memory streamという発想がなかったにょ.

class MyClass
{
  .....
  template<class Archive>
  void serialize(Archive &ar, unsigned int version)
  {
    .....
  }
};

MyClass c;
std::ostringstream ss; // std::ios_base::binaryの指定は不要
                       // textモードとbinaryモードの区別は外部表現と内部表現との
                       // 間の変換に関わるものであり,対応する外部表現が存在しない
                       // string_streamにはtextとbinaryの区別は不要
boost::archive::binary_oarchive oa(ss);
oa << c;
// 以下ss.str()でcのin-memory serializationが取得できる.

何かこんな感じで.えへへへへ・・・・.
#stringstreamの嫌いなところはstringとしてしか内部バッファを取れないところなんだよにゃ〜.sgetnがあるけれど激しく面倒くさいし・・・.iteratorでくるくる回したいのだー!
#CRTPベースなiostreamライブラリがちゅど〜んと登場!これさえあれば上のコードは汎用・型安全・高効率なstd::memcpyになります!みたいことにならないかにゃ・・・.
#あれ?っていうかストリーム出力の結果をoverflowを事実上気にしなくて良いバッファ様のもの,例えばBackInsertionContainerのpush_backにリダイレクトするようなストリームクラスがあればたいそう便利なんじゃ?っていうか何でないの?それとも私が見つけてないだけ?それとも何か問題あるのかな?むむむ?
#あ〜.結局整形のために内部でバッファリングが要るからこれ作ってもstringstream以上のうまみがないな.
#で,iteratorでくるくる回したければistream_iterator使えば良いだけと.
結論:std::stringstreamで十分.ただし整形なしなら余計なバッファリングが必要ないので微妙に需要あるかも.