1

基本的にサブクラスを構築する「ジェネレーター」クラスがあります。このことを使用するには、単純にサブクラス化し、正しいパラメーターを渡して、構築したいオブジェクトを構築します。これらをシリアル化したいのですが、すべてのデータがベースにあるため、サブクラスごとにシリアル化する正当な理由はありません。これが私が例として持っているものです:

#include <boost/serialization/serialization.hpp>
template < typename T >
struct test_base
{
  // works...
  //template < typename Archive >
  //void serialize(Archive &, unsigned int const)
 // {
  //}
};

template < typename T >
void f(test_base<T> const&) {}

struct test_derived : test_base<int>
{
};

namespace boost { namespace serialization {

template < typename Archive, typename T >
void serialize(Archive &, test_base<T> &, unsigned int const)
{
}

}}

#include <boost/archive/binary_oarchive.hpp>
#include <sstream>
int main()
{
  int x = 5;
  test_derived d;
  //boost::serialization::serialize(x, d, 54); // <- works.

  std::ostringstream str;
  boost::archive::binary_oarchive out(str);
  out & d; // no worky.
}

できれば無料版で動いてほしい。それは...ですか?

上記のバージョンは、serialize が test_derived のメンバーではないというエラーを吐き出します。

4

1 に答える 1

0

問題が発生する理由の明確化:
boost::serialization には、シリアル化機能を実装する方法が必要です。クラスメソッドとして、または(あなたの場合)boost::serialization 名前空間で関数を定義する非侵入的な方法として。
したがって、コンパイラは、どの実装を選択するかをどうにかして決定する必要があります。そのため、boost には、boost::serialization::serialize テンプレート関数の「デフォルト」実装があります。
サイン:

template<class Archive, class T>
inline void serialize(Archive & ar, T & t, const BOOST_PFTO unsigned int file_version)


その関数内で、T::serialize(...) への呼び出しがあります。したがって、直感的なバージョンが必要ない場合は、boost::serialization::serialize 関数をデフォルトの関数テンプレートよりも明示的なものでオーバーライドする必要があります。
今問題:
あなたの場合、コンパイラはそれ
がa)パラメータを暗黙的にキャストする必要があるバージョンを選択するかどうかを決定する必要があります(test_derived&からtest_base&へ)
b)キャストせずに汎用関数を使用します(Tはtest_built&です)
コンパイラにバリアント a) を使用しますが、コンパイラは b) を優先 します。

解決策:
本当に良い解決策がわかりません。明示的な型で serialize(...) の実装を生成するマクロを使用すると思います。
それが可能な解決策でない場合は、コンパイラに何を呼び出すかをより明示的に伝えることもできます。

out & *((test_base<int>*)&d);


そしてそれをいくつかのヘルパー関数でラップします (誰もそのようなコードを一日中見たくないため)

これが明確な説明であり、役立つことを願っています

私の説明が明確でない場合に備えて、ここに例を示します:

#include <iostream>
class Base
{
public:
    virtual ~Base()
    {
    }
};

class Derived : public Base
{
public:
    virtual ~Derived()
    {
    }
};


void foo(Base& bar)
{
    std::cout << "special" << std::endl;
}

template<typename T>
void foo(T& bar)
{
    std::cout << "generic" << std::endl;
}

int main()
{
    Derived derived;
    foo(derived);         // => call to generic implementation
    foo(*((Base*) &bla)); // => call to special 
    return 0;
}
于 2010-09-14T22:44:43.917 に答える