C++
Zij aan zij Vergelijkingen van klassieke C ++ voorbeelden opgelost via C ++ versus C ++ 11 versus C ++ 14 versus C ++ 17
Zoeken…
Een container doorlussen
In C ++ kan het doorlopen van een reekscontainer c
als volgt worden gedaan met behulp van indexen:
for(size_t i = 0; i < c.size(); ++i) c[i] = 0;
Hoewel eenvoudig, zijn dergelijke geschriften onderworpen aan veel voorkomende semantische fouten, zoals een verkeerde vergelijkingsoperator of een verkeerde indexeringsvariabele:
for(size_t i = 0; i <= c.size(); ++j) c[i] = 0;
^~~~~~~~~~~~~~^
Looping kan ook worden bereikt voor alle containers die iterators gebruiken, met dezelfde nadelen:
for(iterator it = c.begin(); it != c.end(); ++it) (*it) = 0;
C ++ 11 introduceerde bereikgebaseerd voor lussen en auto
trefwoord, waardoor de code kon worden:
for(auto& x : c) x = 0;
Hier zijn de enige parameters container c
en een variabele x
om de huidige waarde te behouden. Dit voorkomt de eerder genoemde semantische fouten.
Volgens de C ++ 11-standaard is de onderliggende implementatie gelijk aan:
for(auto begin = c.begin(), end = c.end(); begin != end; ++begin)
{
// ...
}
In een dergelijke implementatie is de uitdrukking auto begin = c.begin(), end = c.end();
krachten begin
en end
van hetzelfde type te zijn, terwijl het end
nooit wordt verhoogd of van dereferentie wordt afgeleid. De op bereik gebaseerde lus werkt dus alleen voor containers die zijn gedefinieerd door een paar-iterator / iterator. De standaard C ++ 17 verlicht deze beperking door de implementatie te wijzigen in:
auto begin = c.begin();
auto end = c.end();
for(; begin != end; ++begin)
{
// ...
}
Hier mogen begin
en end
van verschillende typen zijn, zolang ze kunnen worden vergeleken voor ongelijkheid. Dit maakt het mogelijk om meer containers te doorlopen, bijvoorbeeld een container gedefinieerd door een paar iterator / sentinel.