Bonjour,
Lorsque l'on utilise la nouvelle syntaxe pour les boucles en C++11, par exemple :
... alors dans ce cas, data est de type double. On peut accéder à la valeur, mais une fois dans la boucle, on ne connaît pas a priori sa position dans le std::vector. Une solution est d'itérer sois-même à côté :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 std::vector<double> array(10); for (auto data : array) { // ... }
... mais on perd l'intérêt de la nouvelle syntaxe.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 std::vector<double> array(10); size_t i = 0; for (auto data : array) { // ... ++i; }
Du coup, j'ai implémenté moi-même quelque chose d'assez générique (j'ai condensé un peu le code pour que ça soit lisible sur le forum) :
On l'utilise alors comme suit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 template<class T> class pairs_proxy { T& obj; public : pairs_proxy(T& t) : obj(t) {} typedef typename T::iterator proxy_iterator; typedef typename T::const_iterator proxy_const_iterator; class iterator { proxy_iterator iter; explicit iterator(proxy_iterator i) : iter(i) {} public : iterator() = default; iterator& operator ++ () { ++iter; return *this; } iterator operator ++ (int) { iterator tmp = *this; return ++tmp; } iterator& operator -- () { --iter; return *this; } iterator operator -- (int) { iterator tmp = *this; return --tmp; } proxy_iterator& operator * () { return iter; } bool operator == (const iterator& i) const { return iter == i.iter; } bool operator != (const iterator& i) const { return iter != i.iter; } friend class const_iterator; friend class pairs_proxy; }; class const_iterator { proxy_const_iterator iter; explicit const_iterator(proxy_const_iterator i) : iter(i) {} public : const_iterator() = default; const_iterator(const iterator& i) : iter(i.iter) {} const_iterator& operator ++ () { ++iter; return *this; } const_iterator operator ++ (int) { const_iterator tmp = *this; return ++tmp; } const_iterator& operator -- () { --iter; return *this; } const_iterator operator -- (int) { const_iterator tmp = *this; return --tmp; } proxy_const_iterator& operator * () { return iter; } bool operator == (const const_iterator& i) const { return iter == i.iter; } bool operator != (const const_iterator& i) const { return iter != i.iter; } friend class pairs_proxy; }; iterator begin() { return iterator(obj->begin()); } iterator end() { return iterator(obj->end()); } const_iterator begin() const { return const_iterator(obj->begin()); } const_iterator end() const { return const_iterator(obj->end()); } }; template<class T> pairs_proxy<T> pairs(T& t) { return pairs_proxy<T>(t); }
... et c'est en réalité équivalent à l'itération "à l'ancienne" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 std::vector<double> array(10); for (auto iter : pairs(array)) { // ... }
Ma question est alors : existe-t-il déjà quelque chose dans le standard pour faire ce que je souhaite ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 std::vector<double> array(10); for (auto iter = array.begin(); iter != array.end(); ++iter) { // ... }
Et si non, mon implémentation est-elle optimale à votre avis ? Que changeriez-vous ?
PS : Pour l'anecdote, le mot "pairs" est inspiré de Lua :
Si on n'utilise pas pairs dans l'exemple ci-dessus, alors on perd l'information sur idx, et on retrouve une syntaxe très proche du premier morceau de code en haut de ce message :
Code Lua : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 local array = {1, 2, 5, 0, -5, 5.2, 85}; for idx, data in pairs(array) do // 'idx' est l'indice sur lequel on itère (automatiquement) // 'data' est la valeur de array[idx] end
Code Lua : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 local array = {1, 2, 5, 0, -5, 5.2, 85}; for data in array do // ... end
Partager