【问题标题】:Can std::function be serialized?std::function 可以序列化吗?
【发布时间】:2013-08-11 15:10:31
【问题描述】:

这是一个理论问题。假设有一些对象包含订阅这些对象事件的回调函数列表。现在我们要将这些对象存储在磁盘上。 std::function 是可序列化的吗?

【问题讨论】:

  • “实践”有点远:序列化原始函数指针和 FastDelegate 之类的东西可能可能,但你将有大量的修正。 codeproject.com/Articles/7150/… 展示了运行时函数指针实现的一些多样性。从操作系统和加载程序中添加更多复杂性——例如共享对象和 ASLR。相当的任务。我很想阅读低端的编译器+平台特定的技巧;还有可移植的解决方法(我们使用 enum->func LUTs 来处理静态方法)。
  • 好吧,std::function 甚至无法与另一个 std::function 进行比较(operator== 等人),因此序列化会很费力。

标签: c++ serialization theory std-function


【解决方案1】:

没有。

无论何时使用类型擦除(即,将实现细节隐藏在接口后面),在不知道对象的动态类型的情况下唯一可用的操作是接口提供的操作。

C++ 标准中没有序列化,也没有简单的方法来序列化函数(没有反射),因此std::function 接口不提供序列化。

另一方面,没有什么能阻止使用提供序列化支持的Callback基类。

【讨论】:

    【解决方案2】:

    std::function 是一个遵循值语义的类型擦除对象。它公开了复制/移动构造和分配,以及特定签名的执行和销毁。

    这些都不是序列化。

    在内部,std::function 的典型实现是在其构造自参数上创建一个实现助手template 类,该类将上述操作包装在参数上,然后std::function 本身委托其对这些操作的实现到辅助对象。

    该辅助对象的布局将取决于构造的参数的布局(除了它的存在是可选的,并且它的实现依赖于实现)。

    您可以尝试创建一个支持序列化的类似对象,但类型擦除对象依赖于被擦除的类型已经实现了相关操作这一事实。这意味着您只能从至少在鸭子类型级别支持带序列化函数接口的对象构造类型擦除函数带序列化。

    【讨论】:

      【解决方案3】:

      是的,它是,不,它不是。理论上,您可以序列化函数对象将运行的数据,但无论如何您都需要编译代码,因为如果不求助于丑陋的黑客,您将无法执行数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-14
        • 1970-01-01
        相关资源
        最近更新 更多