在C++中实现foreach循环,比for_each更简洁!
浏览:8632次 出处信息
python,c#,java里面都有类似于foreach的结构,stl里面虽然有for_each这个函数,但是感觉使用还是太繁琐了一些,所以就自己实现了一个。 先来看看stl里面的for_each函数,官方文档上的原型如下:
1 |
Function for_each (InputIterator first, InputIterator last, Function f); |
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// for_each example #include <iostream> #include <algorithm> #include <vector> using namespace std; void myfunction (int i) { cout << " " << i; } struct myclass { void operator() (int i) {cout << " " << i;} } myobject; int main () { vector<int> myvector; myvector.push_back(10); myvector.push_back(20); myvector.push_back(30); cout << "myvector contains:"; for_each (myvector.begin(), myvector.end(), myfunction); // or: cout << "\nmyvector contains:"; for_each (myvector.begin(), myvector.end(), myobject); cout << endl; return 0; } |
不只函数原型有点不习惯,而且还要再写一个函数,比起python的实现方式,的确有点繁琐了:
1 2 |
for d in l: print d |
我们来自己实现一个,方法肯定是用宏啦,我们来看一下第一个版本:
1 2 |
#define foreach(container,it,type) \
for(type::iterator it = (container).begin();it!=(container).end();++it) |
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <iostream> #include <string> #include <vector> #include <set> #include <map> using namespace std; #define foreach(container,it,type) \ for(type::iterator it = (container).begin();it!=(container).end();++it) int main(int argc, const char *argv[]) { set<string> s; s.insert("w"); s.insert("a"); s.insert("n"); foreach(s,it,set<string>) { cout<<*it<<endl; } /*map<unsigned,string> m; m[0]="x"; m[1]="w"; foreach(m,it,map<unsigned,string>) { cout<<it->first<<","<<it->second<<endl; }*/ return 0; } |
如果把注释掉的代码打开的话,就会报错,应该是宏无法处理逗号的原因。
而且调用起来还是有点繁琐对吧,python里面并没有要求传入容器类型,我们是不是也能把set
先来看一下这段代码:
1 2 3 |
typeof(10) a; a = 100; cout<<a<<endl; |
这段代码是可以执行的,运行结果是100。从这一点出发,我们是不是能通过typeof(container)获得容器类型,然后通过typeof(container)::iterator创建遍历指针呢,我们来看第二个版本
1 2 |
#define foreach(container,it) \
for(typeof(container)::iterator it = (container).begin();it!=(container).end();++it) |
然而很不幸,这段代码是无法运行的,编译结果如下:
test4.cpp|21| error: expected initializer before "it" test4.cpp|21| error: `it' was not declared in this scope test4.cpp|34| error: expected initializer before "it" test4.cpp|34| error: `it' was not declared in this scope
有没有办法解决呢?
有的,我们用一个曲线救国的方法!typeof(container.begin()) ,哈哈!最终代码如下:
1 2 |
#define foreach(container,it) \
for(typeof((container).begin()) it = (container).begin();it!=(container).end();++it) |
测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <vector> #include <set> #include <map> using namespace std; #define foreach(container,it) \ for(typeof((container).begin()) it = (container).begin();it!=(container).end();++it) int main(int argc, const char *argv[]) { set<string> s; s.insert("w"); s.insert("a"); s.insert("n"); foreach(s,it) { cout<<*it<<endl; } map<unsigned,string> m; m[0]="x"; m[1]="w"; foreach(m,it) { cout<<it->first<<","<<it->second<<endl; } return 0; } |
输入结果如下:
a n w 0,x 1,w
OK!一切正常!这应该是形式比较简单的版本啦,如果各位有什么更好的建议,欢迎留言交流~
ps:
当然,其实你连it这个参数都可以省掉,但是根据pythonic的原则(好吧,我知道自己是在写C++),要简单但不能让人迷惑,所以建议还是把it这个参数保留。
建议继续学习:
- for 循环为何可恨? (阅读:4461)
- 循环、迭代、遍历和递归 (阅读:4456)
- C/C++循环获取文件中的每行数据(别以为很简单!) (阅读:3885)
- 优化次数过多的循环 (阅读:2659)
- 数组的优化循环展开与分割 (阅读:2493)
- Loop Benchmarks (阅读:2394)
- Perl6有用的和有意思的循环 (阅读:1978)
- JavaScript优化循环 (阅读:1867)
- iOS下自己动手造无限循环图片轮播 (阅读:1925)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:一个简单的stl中string的split函数
后一篇:基于DSL风格的代码重构 >>
文章信息
- 作者:Dante 来源: Vimer
- 标签: foreach 循环
- 发布时间:2010-10-25 23:44:57
建议继续学习
近3天十大热文
- [51] Oracle MTS模式下 进程地址与会话信
- [49] 图书馆的世界纪录
- [49] IOS安全–浅谈关于IOS加固的几种方法
- [49] 如何拿下简短的域名
- [45] android 开发入门
- [44] 【社会化设计】自我(self)部分――欢迎区
- [42] 读书笔记-壹百度:百度十年千倍的29条法则
- [42] 界面设计速成
- [41] 视觉调整-设计师 vs. 逻辑
- [40] Go Reflect 性能