Od C++11 lze napsat for
cyklus přes daný výčet hodnot (např. 1, 2, 2, 8, 13
) mnohem jednodušším způsobem, než tomu bylo v C++98. V tomto krátkém příspěvku se podíváme, jak na to. Mrkneme se i na jedno rozšíření připravovaného standardu C++1z, které kód ještě o něco zjednoduší.
Úkol
Napsat for
cyklus iterující přes zadaný výčet hodnot (např. 1, 2, 2, 8, 13
).
Řešení v C++98
V C++98 takovýto for
cyklus šlo zapsat různě, ale nikdy ne tak přehledně, jako v C++11. Jedna z možností je následující:
int values[] = {1, 2, 2, 8, 13}; for (size_t i = 0; i < sizeof values / sizeof values[0]; ++i) { // Aktuální hodnota se získá přes values[i]. }
Tento způsob jsem již zmiňoval.
Řešení v C++11
Od C++11 lze použít std::initializer_list a range-based for loop, což nám umožní následující, přehledný zápis:
#include <initializer_list> int main() { for (auto v : {1, 2, 2, 8, 13}) { // ... } }
Poznámka pro zvídavé: ona syntaxe s využitím {1, 2, 2, 8, 13}
je umožněna dle výjimky v [C++11, 6.5.4/§1]. Bez ní by tento kód nebylo možné napsat, protože {1, 2, 2, 8, 13}
není výraz a nemá typ (typ se ale někdy automaticky dedukuje).
Řešení v C++1z
S využitím terse range-based for loop, což je plánované rozšíření pro připravovaný standard C++1z (očekávaný v roce 2017), půjde kód výše napsat ještě o něco jednodušeji:
#include <initializer_list> int main() { for (v : {1, 2, 2, 8, 13}) { // chybí "auto" // ... } }
Vyzkoušet si jej lze již nyní přes Clang (clang -std=c++1z ...
).
Aktualizace: V seznamu změn u zbrusu nového Clangu 3.6 je napsáno, že podpora pro terse range-based for loop byl zrušena, jelikož tato novinka není už pro C++1z zvažována. V Clangu 3.5 je nicméně podpora funkční.