[陶大妈醒目][c++11] 类似泛型 for_each 算法的 variadic template 实现

fallening 2012-06-17 06:16:55
经常遇到多个类似算法,但是参数数量不一样的,我都是直接 overload 掉了
比如 for_each

template<typename II1, typename F>
F for_each( II1 _ii1, II1 ii1_, F f )
{
while ( _ii1 != ii1_ )
{ f( *_ii1++ ); }

return f;
}

template<typename II1, typename II2, typename F>
F for_each( II1 _ii1, II1 ii1_, II2 _ii2, F f )
{
while ( _ii1 != ii1_ )
{ f( *_ii1++, *_ii2++ ); }

return f;
}

template<typename II1, typename II2, typename II3, typename F>
F for_each( II1 _ii1, II1 ii1_, II2 _ii2, II3 _ii3, F f )
{
while ( _ii1 != ii1_ )
{ f( *_ii1++, *_ii2++, *_ii3++ ); }

return f;
}

template<typename II1, typename II2, typename II3, typename II4, typename F>
F for_each( II1 _ii1, II1 ii1_, II2 _ii2, II3 _ii3, II4 _ii4, F f )
{
while ( _ii1 != ii1_ )
{ f( *_ii1++, *_ii2++, *_ii3++, *_ii4++ ); }

return f;
}


现在问题是,是否存在一种方法,使用 Variadic Templates 技术使得 for_each 直接接受 N 个参数而不用写出多个重载?

比如这种形式
    template<typename II1, typename... IIN, typename F>
F for_each( II1 _ii1, II1 ii1_, IIN... _iin, F f );

尝试了几次没有成功,主要难点在 *_iin 的展开递归上,不知各位有何高见?

...全文
147 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
fallening 2012-06-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

引用 5 楼 的回复:

引用 2 楼 的回复:

楼主试一下这个,你原来的接口不行,因为 template pack parameter 后面不能再有函数形参,否则推导失败。
C/C++ code

#include <iostream>
#include <iomanip>
#include <numeric>
#include <string>
#include ……
[/Quote]

多谢了
我这个先凑合着用吧;结贴睡觉了
ri_aje 2012-06-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 2 楼 的回复:

楼主试一下这个,你原来的接口不行,因为 template pack parameter 后面不能再有函数形参,否则推导失败。
C/C++ code

#include <iostream>
#include <iomanip>
#include <numeric>
#include <string>
#include <vector>

void……
[/Quote]
确实是,我隐约记得之前有人提到 template pack parameter 只能放最后是个问题,好像还试图给出提案,不过标准委员会貌似因为其他原因没有考虑。
fallening 2012-06-17
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

楼主试一下这个,你原来的接口不行,因为 template pack parameter 后面不能再有函数形参,否则推导失败。
C/C++ code

#include <iostream>
#include <iomanip>
#include <numeric>
#include <string>
#include <vector>

void pre_incr () { }
templa……
[/Quote]
多谢多谢,工作没有问题,主要缺点是跟 stl 的接口不一致了,把 lambda 函数放到最前面猛一看很不习惯…………


fallening 2012-06-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

我是来学习的。对于C++0X11你们是从哪里学来的?有什么教程推荐下么??
[/Quote]
基本上没有什么书讲;主要是去看 http://www.open-std.org/ 这里的标准
ri_aje 2012-06-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

我是来学习的。对于C++0X11你们是从哪里学来的?有什么教程推荐下么??
[/Quote]
看标准呗。经典书也开始出更新了,c++ primer plus 6 就有讲一些。
ri_aje 2012-06-17
  • 打赏
  • 举报
回复
楼主试一下这个,你原来的接口不行,因为 template pack parameter 后面不能再有函数形参,否则推导失败。

#include <iostream>
#include <iomanip>
#include <numeric>
#include <string>
#include <vector>

void pre_incr () { }
template <typename T, typename ... Ts>
void pre_incr (T& t, Ts& ... ts) { ++t; pre_incr(ts...); }

template <typename F, typename II1, typename ... IIs>
F for_each (F f, II1 _ii1, II1 ii1_, IIs ... _iis)
{
for (; _ii1 != ii1_; pre_incr(_ii1,_iis...))
{
f(*_ii1,*_iis...);
}
return f;
}

int main ()
{
std::string const string = "c++-template-programming";
std::vector<size_t> indices(string.size());
std::iota(indices.begin(),indices.end(),0);
::for_each([](size_t x, char c)
{ std::cout << std::setw(2) << x << " " << c << std::endl; },
indices.begin(),indices.end(),
string.begin());
return 0;
}
W170532934 2012-06-17
  • 打赏
  • 举报
回复
我是来学习的。对于C++0X11你们是从哪里学来的?有什么教程推荐下么??

64,266

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧