分类目录归档:元编程

编译期遍历std::array

需求

在编译期遍历一个std::array,并且保证遍历的索引为编译期常量。

实现代码:

如何实现函数参数过滤代码点评

前面提出了一个参数过滤的需求,社区的一些朋友给出了实现,在这里做一下点评。

需求

过滤传入的函数参数。假设传入了int, bool, double, bool, structA这几个参数,现在我需要把其中的bool参数去掉,只保留非bool的参数,因此输入的参数经过过滤之后就变成一个tuple<int, double, structA>了。

实现思路:

实现方法有两种(当然,也许还有更多的方法)。

第一种思路

展开变参的过程中忽略特定类型,其它类型的参数重新组成一个tuple,这种方法比较直接了当。社区的Jaly就是这样做的,下面是他的实现代码:

这个代码的实现简洁又灵活,代码很少,并且能支持任意类型的过滤,非常精彩。

除了上面的实现之外,还有一种实现方法,利用c++17的fold expression去过滤,这也是我的实现方法。具体代码如下:

这个实现相比Jaly的实现,代码更多,还不够灵活,不能对任意类型进行过滤。虽然用到了C++17的fold expression,但是没有Jaly的实现那么简洁灵活,而且还用到了运算符重载,存在运算符重载冲突的可能性。算是展示fold expression的一种用法吧。

社区的yiShuiHanFeng实现了过滤bool参数并调用过滤bool后的目标函数,下面是他的实现:

yiShuiHanFeng是通过函数递归调用来过滤bool的,但是他在过滤bool的同时又把需要的参数保留,通过不断把非bool的参数往后放来实现的,最终实现目标函数调用,中间不会生成中间变量,实现得非常精妙,很赞!

第二种思路

在编译期得到过滤之后的参数索引。展开参数类型,排除bool类型,并把非bool类型的参数索引保存到index_sequence,后面根据这个index_sequence就可以得到过滤后的参数。下面是fesil的实现:

这个实现也很棒,也能对任意类型进行过滤,实现用到了c++17的if constexpr,让代码变得更简单了,虽然相比第一种实现方法稍显复杂一点,但仍然是一个不错的思路。

总结

这个需求大家积极参与并且给出了精彩的实现,非常好。可以看到同一个需求却有着不同的实现思路和实现方法,体现了元编程灵活与精巧。

本次实现得最好的是Jaly,他的代码最短又灵活,其次是fesil,yiShuiHanFeng的参数移动也很精妙。