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

Od Petr Zemek, 2015-02-28

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

Obsah tohoto pole je soukromý a nebude veřejně zobrazen.

Filtrované HTML (využíváno)

  • Povolené HTML značky: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <table>
  • Zvýraznění syntaxe kódu lze povolit přes následující značky: <code>, <blockcode>, <bash>, <c>, <cpp>, <haskell>, <html>, <java>, <javascript>, <latex>, <perl>, <php>, <python>, <ruby>, <rust>, <sql>, <text>, <vim>, <xml>, <yaml>.
  • Řádky a odstavce se zalomí automaticky.
  • Webové a e-mailové adresy jsou automaticky převedeny na odkazy.
CAPTCHA
8 + 8 =
Vyřešte tento jednoduchý matematický příklad a vložte výsledek. Např. pro 1+3 vložte 4.
Nějak se mi tady rozmohl spam, takže poprosím o ověření.