In range-based for loop index bekommen
-
hustbaer schrieb:
Hab ich da was übersehen, also geht das auch irgendwie einfach & elegant?
Kommt drauf an, was man unter einfach und elegant versteht. Statt Macros zu verwenden würde ich std::for_each erweitern:
#include <iostream> #include <vector> template<class InputIt, class Function> Function for_each(InputIt first, InputIt last, Function f) { for (int idx = 0; first != last; ++first, ++idx) { f(*first, idx); } return f; } int main() { std::vector<int> v = { 1, 2, 3, 4 }; for_each( v.begin(), v.end(), []( auto& val, int idx ) { std::cerr << idx << " = " << val << "\n"; }); }
-
hustbaer schrieb:
Mir fällt jetzt aber z.B. nix ein wie man das mit range based for umsetzen könnte. Und wenn man range based for emulieren muss, dann kommt wieder so ein Monster wie
BOOST_FOREACH
raus.Hab ich da was übersehen, also geht das auch irgendwie einfach & elegant?
Können wir ja mal drüber reden, denn mir gefällt die Lösung, die ich vor Jahren mal geschrieben habe, nicht wirklich.
#define FOREACH_I(NAME,RANGE) for (size_t i=size_t(-1),_fe_continue=true;_fe_continue;_fe_continue=false) for (auto&& NAME : RANGE) if (true | ++i)
An der Lösung ist besonders problematisch, dass der IDE die Definition des Makro natürlich bekannt ist und daher den Block nach dem foreach_i automatisch einrückt:
FOREACH_I(v,values) { }
Andere Ideen ohne dieses Problem sind willkommen (alle Features bis C++17 erlaubt).
-
hustbaer schrieb:
Hab ich da was übersehen, also geht das auch irgendwie einfach & elegant?
Hatten wir das nicht schon? https://www.c-plusplus.net/forum/p2552252#2552252
-
@manni66 & Arcoth
Ich hab ganz bewusst den Beitrag von ;sergey zitiert wo er eine Makro-Lösung erwähnt die sich so wie von ihm gezeigt aufrufen lässt.Dass es grundsätzlich auch anders als mit Makro geht ist schon klar.
-
;sergey schrieb:
#define FOREACH_I(NAME,RANGE) for (size_t i=size_t(-1),_fe_continue=true;_fe_continue;_fe_continue=false) for (auto&& NAME : RANGE) if (true | ++i)
Du solltest den Loop-Body auf jeden Fall in den else Zweig verschieben. Sonst gibt's Probleme bei sowas wie
if (foo) FOREACH_I(v, values) v += i; else bar();
Also statt
if (true | ++i)
lieber sowas wieif (++i, false) {} else
Und genau das, also der "if Trick", ist das an was ich nicht gedacht hatte.
;sergey schrieb:
An der Lösung ist besonders problematisch, dass der IDE die Definition des Makro natürlich bekannt ist und daher den Block nach dem foreach_i automatisch einrückt:
FOREACH_I(v,values) { }
Meine IDE ist für sowas zu doof, die rückt das nur 1x ein