Jste zde

Zajímavosti z C++: Iterace přes výčet hodnot

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

Přidat komentář