Zazwyczaj iteratory są używane do uzyskiwania dostępu do elementów kontenera w sposób liniowy; jednakże dzięki „iteratorom dostępu swobodnego” możliwy jest dostęp do dowolnego elementu w taki sam sposób, jakoperator[]
.
Aby uzyskać dostęp do dowolnych elementów w wektorze vec
, możesz użyć:
vec.begin() // 1st
vec.begin()+1 // 2nd
// ...
vec.begin()+(i-1) // ith
// ...
vec.begin()+(vec.size()-1) // last
Poniżej znajduje się przykład typowego wzorca dostępu (wcześniejsze wersje C ++):
int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
Zaletą korzystania z iteratora jest to, że ten sam wzorzec można zastosować w innych kontenerach :
sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
sum += *it;
}
Z tego powodu bardzo łatwo jest stworzyć kod szablonu, który będzie działał tak samo niezależnie od typu kontenera . Kolejną zaletą iteratorów jest to, że nie zakładają one, że dane są rezydentne w pamięci; na przykład można stworzyć iterator do przodu, który może czytać dane ze strumienia wejściowego lub po prostu generuje dane w locie (np. generator zakresu lub liczb losowych).
Inna opcja przy użyciu std::for_each
i lambd:
sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });
Od C ++ 11 możesz użyć, auto
aby uniknąć określania bardzo długiej, skomplikowanej nazwy typu iteratora, jak widać wcześniej (lub nawet bardziej złożonej):
sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
Ponadto istnieje prostszy wariant dla każdego:
sum = 0;
for (auto value : vec) {
sum += value;
}
I wreszcie jest miejsce, w std::accumulate
którym musisz uważać, czy dodajesz liczby całkowite, czy zmiennoprzecinkowe.