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í.