Pravděpodobně víte, že u for
cyklů v C (od C99) a C++ lze iterační proměnnou definovat přímo v inicializační části cyklu, tedy např. for (int i = 0; ...)
. Dokonce lze proměnných definovat více, např. for (int i = 0, j = 1; ...)
. V takovém případě ale musí mít shodný typ. Co když ale potřebujeme iterovat přes více proměnných, jejichž typ se liší? Je to možné, nebo je potřeba jednu z nich definovat před cyklem? Odpověď se dozvíte v tomto příspěvku.
O co nám jde
Dejme tomu, že potřebujeme iterovat přes proměnné typu int
a double
pomocí for
cyklu (ať už je důvod jakýkoliv, to nás teď nezajímá). Možnost, která vás napadne, je určitě tato:
double d = 0.0; for (int i = 0; i < 10 && d < 10.0; i++, d += 0.4) { // ... }
To samozřejmě funguje. Jelikož mají ale proměnné různý typ, tak nelze napsat
// Nepřeložitelné :(. for (int i = 0, double d = 0.0; i < 10 && d < 10.0; i++, d += 0.4) { // ... }
protože to není syntakticky korektní. Takže se naskýtá následující otázka.
Jde to nějak udělat?
Ano :). Například takto:
for (struct {int i; double d;} loop = {0, 0.0}; loop.i < 10 && loop.d < 10.0; loop.i++, loop.d += 0.4) { // ... }
Definujeme si anonymní strukturu, která obsahuje proměnné, přes které budeme iterovat. V cyklu pak budeme k těmto proměnných přistupovat přes proměnnou loop
, kterou jsme si definovali a inicializovali v inicializační části cyklu. Kód výše funguje jak v C (od C99), tak v C++.
Poznámka na závěr
V příspěvku jsem chtěl jen ukázat, že něco takového jde. To, zda to dělat, je však věc jiná, protože podobný kód může být hůře čitelný. Takže pokud byste to chtěli použít, tak se raději dvakrát zamyslete, zda není jiná, čitelnější možnost.
Nebyla by zde vhodnější
Nebyla by zde vhodnější tuple?
Re: Nebyla by zde vhodnější
Možných řešení je více. Já jsem zvolil klasickou strukturu, protože toto řešení funguje jak v C, tak v C++. Co se týče té
std::tuple
, tak struktura je podle mě lepší řešení, protože lze jednotlivé proměnné pojmenovat. Ustd::tuple
je možné k přístupu k položkám použít jen index (C++11) či typ (až od C++14).