これは理論的な問題です。それらのオブジェクトのイベントにサブスクライブされたコールバック関数のリストを含むいくつかのオブジェクトがあるとします。これらのオブジェクトをディスクに保存します。std::function
シリアライズ可能ですか?
3 に答える
いいえ。
型の消去 (つまり、実装の詳細をインターフェイスの背後に隠す) を使用する場合は常に、オブジェクトの動的な型を知らなくても利用できる操作は、インターフェイスによって提供される操作だけです。
C++ 標準にはシリアル化がなく、(リフレクションなしで)関数std::function
をシリアル化する簡単な方法もないため、インターフェイスはシリアル化を提供しません。
一方、シリアライゼーションをサポートする基本クラスを使用することを妨げるものは何もありません。Callback
std::function
値のセマンティクスに従う型消去オブジェクトです。これは、コピー/移動の構築と割り当て、特定の署名の実行、および破棄を公開します。
これらはどれもシリアル化されていません。
内部的には、 の典型的な実装は、構築元の引数にstd::function
実装ヘルパーtemplate
クラスを作成することです。これは、上記の操作を引数にラップし、std::function
それ自体がそれらの操作の実装をヘルパー オブジェクトに委譲します。
そのヘルパー オブジェクトのレイアウトは、構築された引数のレイアウトに依存します (その存在がオプションであり、その実装が実装に依存することに加えて)。
シリアル化をサポートする同様のオブジェクトを作成しようとすることもできますが、型消去オブジェクトは、消去される型が問題の操作を既に実装しているという事実に依存しています。つまり、少なくともダックタイプ レベルでシリアライゼーション付き関数インターフェイスをサポートするオブジェクトからのみ、タイプが消去されたシリアライゼーション付き関数を構築できます。