std::function可以进行序列化吗?

8

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


1
有点离题的“练习”:可能可以序列化原始函数指针和像FastDelegate这样的东西,但你会有很多修正。 http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible 展示了运行时函数指针实现的多样性。从操作系统和加载器中添加更多复杂性--例如共享对象和ASLR。相当棘手的任务。我很想读一下关于低端编译器+平台特定黑客以及可移植的解决方法(我们已经使用枚举->功能LUT用于静态方法)。 - leander
嗯,std::function 甚至不能与另一个 std::function 进行比较(例如 operator==),因此序列化可能有些困难。 - dalle
3个回答

6

不。

每当使用类型抹除(即将实现细节隐藏在接口后面)时,不知道对象的动态类型而可用的唯一操作是由接口提供的操作。

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

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


5

std::function是一种遵循值语义的类型擦除对象。它支持复制/移动构造和赋值,执行特定签名的操作,并进行销毁。

但它并不包含序列化功能。

通常情况下,std::function会在其构建参数上创建一个实现帮助器template类。该类将对参数上述操作进行包装,然后std::function本身将把这些操作的实现委托给辅助对象。

该辅助对象的布局将取决于所构建参数的布局(除了存在性是可选的外,其实现也是依赖于具体实现的)。

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


0

是的,也不是。理论上,您可以序列化函数对象将要运行的数据,但无论如何都需要编译代码,因为您不能执行数据而不采用丑陋的黑客技巧。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接