いいえ。ただし、いくつかの制限された解決策があります。
最も期待できるのは、送信コードと受信コード(異なるコンピューター内またはシリアル化の前後のいずれか)に共通するある種のグローバルマップ(キー文字列など)に関数を登録することです。次に、関数に関連付けられた文字列をシリアル化して、反対側で取得できます。
具体的な例として、ライブラリHPXは、HPX_ACTIONと呼ばれるものでこのようなものを実装します。
これには多くのプロトコルが必要であり、コードの変更に関しては脆弱です。
しかし、結局のところ、これは、プライベートデータを使用してクラスをシリアル化しようとするものと同じです。ある意味で、関数のコードはそのプライベート部分です(引数とリターンインターフェイスはパブリック部分です)。
コードをどのように編成するかに応じて、これらの「オブジェクト」はグローバルまたは共通になり、すべてがうまくいけば、ある種の事前定義されたランタイム間接参照を介してシリアル化および逆シリアル化中に使用できます。
これは大まかな例です。
シリアライザーコード:
// common:
class C{
double d;
public:
C(double d) : d(d){}
operator(double x) const{return d*x;}
};
C c1{1.};
C c2{2.};
std::map<std::string, C*> const m{{"c1", &c1}, {"c2", &c2}};
// :common
main(int argc, char** argv){
C* f = (argc == 2)?&c1:&c2;
(*f)(5.); // print 5 or 10 depending on the runtime args
serialize(f); // somehow write "c1" or "c2" to a file
}
デシリアライザーコード:
// common:
class C{
double d;
public:
operator(double x){return d*x;}
};
C c1;
C c2;
std::map<std::string, C*> const m{{"c1", &c1}, {"c2", &c2}};
// :common
main(){
C* f;
deserialize(f); // somehow read "c1" or "c2" and assign the pointer from the translation "map"
(*f)(3.); // print 3 or 6 depending on the code of the **other** run
}
(コードはテストされていません)。
これにより、多くの一般的で一貫性のあるコードが強制されますが、環境によっては、これを保証できる場合があることに注意してください。コードを少し変更すると、論理的なバグを検出するのが困難になる可能性があります。
また、ここではグローバルオブジェクト(無料の関数で使用できます)で遊んでいましたが、スコープ付きオブジェクトでも同じことができます。より難しいのは、ローカルでマップを確立する方法です(#include
ローカルスコープ内の共通コード?)