声明:本文少量代码转载自Alex Allain的文章 http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html
很多语言都有Range-based for loops这个功能,现在C++终于知道把这个重要功能加进语法中了。这个功能实在不知道该怎么翻译,语文没有学到家。
基本语法
for ( range_declaration : range_expression) loop_statement
比如说:
1. vector<int> vec;
2. vec.push_back( 1 );
3. vec.push_back( 2 );
4.
5. for (int i : vec )
6. {
7. cout << i;
8. }
for语言这么写可以很方便地遍历vector这类的容器。具体什么样的东西可以遍历呢?这个留在后面说。
对于比较复杂的容器可以用auto语句来简化类型声明
1. map<string, string> complexVector;
2. for ( auto complexVectorEntry : complexVector )
3. {
4. " < " << complexVectorEntry.second << ">" << endl;
5. }
这两个例子中都没有修改遍历元素的值。如果你要想修改它们的值,请使用引用类型
1. vector<int> vec;
2. vec.push_back( 1 );
3. vec.push_back( 2 );
4.
5. for (auto& i : vec )
6. {
7. i++;
8. }
continue语句来开始下一次迭代,使用break跳出循环。这一点和普通的for循环一样。
深入分析
1. for ( range_declaration : range_expression) loop_statement
“等价于”
1. {
2. auto && __range = range_expression ;
3. auto __begin = begin_expr(__range);
4. auto __end = end_expr(__range);
5. for (;__begin != __end; ++__begin) {
6. range_declaration = *__begin;
7. loop_statement
8. }
9. }
请注意,“等价于”并不表示编译器就是这么实现range-based for loops的。只是说两者的运行效果等价
begin_expr 和 end_expr 的定义如下:
- 对于数组类型 begin_expr和end_expr分别等于(__range)和(__range + __bound)
- 对于STL中的容器,两者分别等于__range.begin()和__range.end()
- 对于其他类型,两者分别等于begin(__range)和end(__range)。编译器将会通过参数类型来找到合适的begin和end函数
让自定义的类可以迭代
通过ranged-based for loops的等价语句可以看出,可以知道只要符合一定的要求,那么自己定义的类也可以放在ranged-based for loops中进行迭代。事实上要想进行迭代,一个类需要满足以下条件:
- begin函数和end函数,作用是分别指向第一个数据和最后一个数据。返回值是一个可以自己定义的迭代器。既可以是成员函数,也可以是非成员函数。
- 迭代器本身支持* ++ !=运算符,既可以是成员函数,也可以是非成员函数。
比如说下面这个类:
1. #include <iostream>
2.
3. using namespace std;
4.
5.
6. class IntVector;
7.
8. class Iter
9. {
10. public:
11. const IntVector* p_vec, int pos)
12. : _pos( pos )
13. , _p_vec( p_vec )
14. { }
15.
16. // these three methods form the basis of an iterator for use with
17. // a range-based for loop
18. bool
19. const Iter& other) const
20. {
21. return _pos != other._pos;
22. }
23.
24. // this method must be defined after the definition of IntVector
25. // since it needs to use it
26. int operator* () const;
27.
28. const Iter& operator++ ()
29. {
30. ++_pos;
31. return *this;
32. }
33.
34. private:
35. int _pos;
36. const IntVector *_p_vec;
37. };
38.
39. class IntVector
40. {
41. public:
42. IntVector ()
43. {
44. }
45.
46. int get (int col) const
47. {
48. return _data[ col ];
49. }
50. const
51. {
52. return Iter( this, 0 );
53. }
54.
55. const
56. {
57. return Iter( this, 100 );
58. }
59.
60. void set (int index, int val)
61. {
62. _data[ index ] = val;
63. }
64.
65. private:
66. int _data[ 100 ];
67. };
68.
69. int
70. Iter::operator* () const
71. {
72. return _p_vec->get( _pos );
73. }
74.
75.
76. int main()
77. {
78. IntVector v;
79. for ( int i = 0; i < 100; i++ )
80. {
81. v.set( i , i );
82. }
83. for ( int i : v ) { cout << i << endl; }
84. }
IntVector就是一个想要进行迭代的类。它的being和end函数返回一个迭代器Iter。而Iter支持* != ++运算符。
标签:11,__,begin,based,int,range,Range,vec,const From: https://blog.51cto.com/u_15923385/5971866