User-Defined Data Types in Messages(用户自定义类型)
All user-defined types must be explicitly “announced” so that CAF can (de)serialize them correctly.

之前干活,一开始不知道CAF自带序列化,都用boost库来做序列化,就是变string 类型发送,发现很多STL有些搞搞比较麻烦,发现诶?CAF居然比boost库好使!

那么就来搞一下看看.

先看一个例子(也是usermanual 里唯一的一个例子,呵呵呵~)其他的例子在github官网里https://github.com/actor-framework/actor-framework/tree/master/examples/type_system (就五个收益很大)

没看错就是那么简单的使用,announce函数。第一个参数是一个string那么之后就是他的所有成员。怎么实现我也不是很懂,上图

大致就是TS 就是参数的类型,可以是可变长度,然后检查他们的类型,我第一看到Is_pod 查了一下(pod类型 是plain old data)就是完全兼容C语言的编程的。(涨姿势了~)

还有uniform_type_info是CAF自己的一个关于类型什么的(没深究,只知道与RTTI有关)。还有一个重要的地方就是你必须写明你要发送的结构体的比较函数 ==(下面代码上有)

进入正题。(announce1.cpp)代码有一点点小长但是信息量很大。

// POD struct
struct foo {std::vector<int> a;int b;
};// announce requires foo to have the equal operator implemented
bool operator==(const foo& lhs, const foo& rhs) {return lhs.a == rhs.a && lhs.b == rhs.b;
}// a pair of two ints
using foo_pair = std::pair<int, int>;// another pair of two ints
using foo_pair2 = std::pair<int, int>;// a struct with member vector<vector<...>>
struct foo2 {int a;vector<vector<double>> b;
};bool operator==(const foo2& lhs, const foo2& rhs) {return lhs.a == rhs.a && lhs.b == rhs.b;
}// receives `remaining` messages
void testee(event_based_actor* self, size_t remaining) {auto set_next_behavior = [=] {if (remaining > 1) testee(self, remaining - 1);else self->quit();};self->become (// note: we sent a foo_pair2, but match on foo_pair// that's safe because both are aliases for std::pair<int, int>[=](const foo_pair& val) {cout << "foo_pair("<< val.first << ", "<< val.second << ")"<< endl;set_next_behavior();},[=](const foo& val) {cout << "foo({";auto i = val.a.begin();auto end = val.a.end();if (i != end) {cout << *i;while (++i != end) {cout << ", " << *i;}}cout << "}, " << val.b << ")" << endl;set_next_behavior();});
}int main(int, char**) {// announces foo to the libcaf type system;// the function expects member pointers to all elements of fooannounce<foo>("foo", &foo::a, &foo::b);// announce foo2 to the libcaf type system,// note that recursive containers are managed automatically by libcafannounce<foo2>("foo2", &foo2::a, &foo2::b);// serialization can throw if types are not announced properlytry {// init some test data
    foo2 vd;vd.a = 5;vd.b.resize(1);vd.b.back().push_back(42);// serialize test datavector<char> buf;binary_serializer bs(std::back_inserter(buf));bs << vd;// deserialize written test data from buffer
    binary_deserializer bd(buf.data(), buf.size());foo2 vd2;uniform_typeid<foo2>()->deserialize(&vd2, &bd);// deserialized data must be equal to original inputassert(vd == vd2);// announce std::pair<int, int> to the type systemannounce<foo_pair>("foo_pair", &foo_pair::first, &foo_pair::second);// libcaf returns the same uniform_type_info// instance for the type aliases foo_pair and foo_pair2assert(uniform_typeid<foo_pair>() == uniform_typeid<foo_pair2>());}catch (std::exception& e) {cerr << "error during type (de)serialization: " << e.what() << endl;return -1;}// spawn a testee that receives two messages of user-defined typeauto t = spawn(testee, size_t{2});{ // lifetime scope of self
    scoped_actor self;// send t a fooself->send(t, foo{std::vector<int>{1, 2, 3, 4}, 5});// send t a foo_pair2self->send(t, foo_pair2{3, 4});}await_all_actors_done();shutdown();
}

一开始看,就是声明了两种结构体。foo 和foo2,foo2里面有vector<vector<double>> b(其实这里就告诉我们,它不但支持STL,还支持嵌套,而且我亲测pair,map都是可以的。其他应该也没问题吧。)

然后testee里定义了接受两种类型的消息一种是<int,int>(不管别名),一种是结构体foo 是的没看错,都不用序列化了,直接传(// note that recursive containers are managed automatically by libcaf)。

真心方便,然后是main函数里,使用了二进制去序列化类,再使用反序列化,整个过程就像用读文件非常的方便(注意捕获异常)。那么在最后的scoped_actor send也直接把类传过去非常的方便。

为了证明好用,支持remote actor我写了一个很难看的代码。

#include <vector>
#include <iostream>
#include "caf/all.hpp"
#include "caf/io/all.hpp"
using std::cout;
using std::endl;
using std::vector;
using std::map;
using std::pair;
using namespace caf;struct foo {std::vector<vector<map<int,pair<int,int>>>> a;int b;
};
bool operator==(const foo& lhs, const foo& rhs) {return lhs.a == rhs.a && lhs.b == rhs.b;
}
// receives `remaining` messages
void testee(event_based_actor* self) {self->become ([=](const foo& val) {aout(self)<<"get it"<<endl;});
}
int main(int, char**) {
//  announce<foo2>("foo2", &foo2::a, &foo2::b);announce<foo>("foo", &foo::a, &foo::b);auto actor = spawn(testee);caf::io::publish(actor,10000);{ // lifetime scope of self
    scoped_actor self;auto remoter = caf::io::remote_actor("localhost", 10000);self->send(remoter, foo{std::vector<vector<map<int,pair<int,int>>>>{},1,});}await_all_actors_done();shutdown();
}

结果为

不得不服还是很方便的!

码字不容易,求粉丝~互粉呀~

转载于:https://www.cnblogs.com/zhejiangxiaomai/p/5259625.html

CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)相关推荐

  1. 结构体的嵌套 自身嵌套 相互嵌套

    什么是结构体的嵌套? 在结构体的定义中,结构体的成员又是另外一个结构体的变量. 结构体嵌套的问题有哪些? 结构体的自引用,就是在结构体内部,包含指向自身类型结构体的指针. 结构体的相互引用,就是说在多 ...

  2. 【C 语言】结构体 ( 结构体中嵌套二级指针 | 为 结构体内的二级指针成员 分配内存 | 释放 结构体内的二级指针成员 内存 )

    文章目录 一.结构体中嵌套二级指针 1.结构体中嵌套二级指针 类型声明 2.为 结构体内的二级指针成员 分配内存 3.释放 结构体内的二级指针成员 内存 二.完整代码示例 一.结构体中嵌套二级指针 1 ...

  3. 【C 语言】结构体 ( 结构体中嵌套一级指针 | 分配内存时先 为结构体分配内存 然后再为指针分配内存 | 释放内存时先释放 指针成员内存 然后再释放结构头内存 )

    文章目录 一.结构体中嵌套一级指针 1.声明 结构体类型 2.为 结构体 变量分配内存 ( 分配内存时先 为结构体分配内存 然后再为指针分配内存 ) 3.释放结构体内存 ( 释放内存时先释放 指针成员 ...

  4. C语言 结构体 联合体 | 嵌套使用

    一.简单的实例分析 题目:获取0x12345678各个字节. 答案: //方法一: #include <stdio.h>typedef unsigned int uint32_t; typ ...

  5. golang json转结构体中嵌套多个数组_ElasticSearch第六篇:复合数据类型-数组,对象...

    在ElasticSearch中,使用JSON结构来存储数据,一个Key/Value对是JSON的一个字段,而Value可以是基础数据类型,也可以是数组,文档(也叫对象),或文档数组,因此,每个JSON ...

  6. go var type 互转_Go语言学习笔记(第九章) 结构体

    Go语言基础之结构体 Go语言中没有"类"的概念,也不支持"类"的继承等面向对象的概念.Go 通过类型别名(alias types)和结构体的形式支持用户自定义 ...

  7. 技巧:Go 结构体如何转换成 map[string]interface{}

    本文介绍了Go语言中将结构体转成map[string]interface{}时你需要了解的"坑",也有你需要知道的若干方法. 我们在Go语言中通常使用结构体来保存我们的数据,例如要 ...

  8. Go语言基础之结构体

    转载地址:https://www.liwenzhou.com/posts/Go/10_struct/ Go语言中没有"类"的概念,也不支持"类"的继承等面向对象 ...

  9. 【Golang第8章:面向对象编程】Go语言的结构体是什么,怎么声明;Golang方法的调用和声明;go语言面向对象实例,go语言工厂模式;golang面向对象的三大特性:继承、封装、多态

    介绍 这个是在B站上看边看视频边做的笔记,这一章是Glang面向对象编程 这一章内容较多,内容有Go语言的结构体是什么,怎么声明:Golang方法的调用和声明:go语言面向对象实例,go语言工厂模式: ...

最新文章

  1. 漫谈BCH Token方案
  2. 青少年蓝桥杯_2020_每日一题_11.03_输出M与N之间符合要求的数据
  3. 中国游戏公司研运一体发展专题分析2020
  4. 2-3:C++快速入门之缺省参数
  5. Windows10远程桌面连接提示:出现身份验证错误,要求的函数不受支持
  6. unity怎么导入系统的树_unity3d 随机添加树木
  7. 公众号点击图片变成另一张_公众号互动内容:小众潮流or下一个风口?| 新榜观察...
  8. 中山大学2018年数学分析高等代数考研试题
  9. 什么是JavaSE/JavaEE/JavaME?
  10. 高仿京东分类效果(Scroll+Fragment)
  11. Java语言,基于TCP编写一个简单的Client/Server 网络应用程序。
  12. 基于Nonebot2搭建QQ机器人实战篇(一)
  13. php计算qqbkn,js解密之QQ的bkn值,获取QQ群成员信息,获取QQ好友列表信息
  14. 华科_图形学笔记_07_投影变换
  15. 【Python工具】Python版本的天眼查,是不是就很nice啦 | 附带源码
  16. html如何设置打印分页打印出来,网页中如何用 CSS 设置打印分页符
  17. finalize机制
  18. 传统OA厂商举步维艰
  19. 提高设计水平的35个有用的Photoshop样式下载
  20. 今天给大家介绍下APPS品牌相关网络变压器

热门文章

  1. 判断一个无符号整数是不是2的n次幂的幂
  2. Android卷一全文 第一章 阅读前的准备工作
  3. [react] 在react中怎样改变组件状态,以及状态改变的过程是什么?
  4. 前端学习(3272):js中this的使用箭头函数
  5. [css] 用CSS绘制一个红色的爱心
  6. [css] 固定的外框尺寸,里面的图片尺寸不固定,如何让图像自适应外框呢?
  7. 工作190:页面数据不显示
  8. 前端学习(2479):接口文档使用
  9. 前端学习(2369):组件的创建使用和组件的生命周期
  10. 前端学习(2224):react之函数式组件