博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
seastar中apply模板的实现
阅读量:6256 次
发布时间:2019-06-22

本文共 3347 字,大约阅读时间需要 11 分钟。

我在阅读seastar的源码时(这并不代表我熟悉seastar),偶然发现了seastar把tuple里的每一个element传给一个函数作为参数,这让我很好奇它是如何实现的,让我不自量力地分析一下。

seastar有个头文件apply.hh包含如下代码:

namespace seastar {                                                                                                                                             template 
struct apply_helper; template
struct apply_helper
> { static auto apply(Func&& func, Tuple args) { return func(std::get
(std::forward
(args))...); } }; template
inline auto apply(Func&& func, std::tuple
&& args) { using helper = apply_helper
&&, std::index_sequence_for
>; return helper::apply(std::forward
(func), std::move(args)); } template
inline auto apply(Func&& func, std::tuple
& args) { using helper = apply_helper
&, std::index_sequence_for
>; return helper::apply(std::forward
(func), args); } template
inline auto apply(Func&& func, const std::tuple
& args) { using helper = apply_helper
&, std::index_sequence_for
>; return helper::apply(std::forward
(func), args); }

以上这段代码实现的功能是把通过tuple打包的各个element数据拆开,并作为一个个参数去调用其他函数,下面展示如何使用它:

void print(int i, double f){    std::cout << "i:" << i << " f:" << f << '\n';}int main(){    std::tuple
values(1, 2.3); //对数据1和2.3打包 apply(print, values); //调用 print, 把1和2.3作为调用参数}

以上就是把值1和2.3打包,然后通过apply把这些打包的参数通过apply来调用函数print。

上面seastar中apply_helper的主模板没有定义,只是写了一个声明:

template 
struct apply_helper;

然后就是准对第三个模板参数做了部分特化,这第三个参数用的到就是index_sequence模板实例类型:

template 
struct apply_helper
> { static auto apply(Func&& func, Tuple args) { return func(std::get
(std::forward
(args))...); } };

这个apply静态函数的秘密就是利用index_sequence模板实例化时携带的非类型可变参数列表"I...",利用编译器自动对可变参数列表的展开,把这些参数列表里的一个个参数去调用std::get,而这个get则是获取tuple里由Index指定的element。Index是一个整形值。注意调用的方式,get后面跟随一个...操作符:

std::get(std::forward
(args))...

它把index_sequence实例化的参数列表I的每一个参数去分别调用get,由编译器自动重复这个过程。

例如,如果你有index_sequence<1,2,3>这个模板实例定义的类型,那么

func(std::get(std::forward
(args))...)

的意思就是:

func(std::get<1>(std::forward(args)), std::get<2>(std::forward(args)), std::get<3>(std::forward(args)))

STL中的index_sequence_for模板的定义

template
using index_sequence_for = make_index_sequence
;

具体细节我不多讲了,有兴趣可以去看libstdc++头文件的实现,位于utility头文件。

它的作用就是为给定的一个参数列表,实例化模板index_sequence得到一个新的类型,该类型的模板参数是一系列索引号列表:

例如 index_sequence_for生成一个实例化类型:

index_sequence<0,1,2>。
这样0,1,2这个参数列表就可以用在apply一系列的模板中。

由于在apply代码中,模板演绎时tuple始终不丢弃,所以实际上我们在展开这些tuple element作为函数调用的参数时,只需要一系列序号让编译器去重复调用get模板,这就是index_sequence的作用所在。

转载地址:http://ogxsa.baihongyu.com/

你可能感兴趣的文章
iOS数据持久化存储之属性列表
查看>>
最后冲刺时间
查看>>
前端开发薪资之各地区对比(图文分析)
查看>>
jquery简单的大背景banner图片全屏切换
查看>>
java疑问
查看>>
JAVAEE 介绍
查看>>
视图和路由
查看>>
优酷新版播放器站外调用代码详解
查看>>
Python之操作符优先级
查看>>
【学习笔记】PHP会话控制
查看>>
面试题 17:合并两个排序的链表
查看>>
Linux命令--链接文件的那些事
查看>>
您对无法重新创建的表进行了更改或者启用了“阻止保存要求重新创建表的更改”选项...
查看>>
《梦断代码》读后感02
查看>>
java面试资料总结
查看>>
ubuntu 16.04 安装PhpMyAdmin
查看>>
c#中的常用ToString()方法总结
查看>>
ajax五,jsonp跨域的本质
查看>>
调用打印机打印
查看>>
poj1742
查看>>