Saya merasa bahwa tidak ada jawaban di sini yang menjelaskan mengapa saya suka iterator sebagai konsep umum alih-alih pengindeksan ke dalam wadah. Perhatikan bahwa sebagian besar pengalaman saya menggunakan iterator sebenarnya tidak berasal dari C ++ tetapi dari bahasa pemrograman tingkat tinggi seperti Python.
Antarmuka iterator membebankan lebih sedikit persyaratan pada konsumen atas fungsi Anda, yang memungkinkan konsumen untuk berbuat lebih banyak dengannya.
Jika semua yang Anda butuhkan adalah dapat meneruskan-iterate, pengembang tidak terbatas menggunakan wadah yang dapat diindeks - mereka dapat menggunakan implementasi kelas apa pun operator++(T&)
, operator*(T)
dan operator!=(const &T, const &T)
.
#include <iostream>
template <class InputIterator>
void printAll(InputIterator& begin, InputIterator& end)
{
for (auto current = begin; current != end; ++current) {
std::cout << *current << "\n";
}
}
// elsewhere...
printAll(myVector.begin(), myVector.end());
Algoritme Anda berfungsi untuk case yang Anda butuhkan - iterasi melalui vektor - tetapi juga dapat berguna untuk aplikasi yang tidak perlu Anda antisipasi:
#include <random>
class RandomIterator
{
private:
std::mt19937 random;
std::uint_fast32_t current;
std::uint_fast32_t floor;
std::uint_fast32_t ceil;
public:
RandomIterator(
std::uint_fast32_t floor = 0,
std::uint_fast32_t ceil = UINT_FAST32_MAX,
std::uint_fast32_t seed = std::mt19937::default_seed
) :
floor(floor),
ceil(ceil)
{
random.seed(seed);
++(*this);
}
RandomIterator& operator++()
{
current = floor + (random() % (ceil - floor));
}
std::uint_fast32_t operator*() const
{
return current;
}
bool operator!=(const RandomIterator &that) const
{
return current != that.current;
}
};
int main()
{
// roll a 1d6 until we get a 6 and print the results
RandomIterator firstRandom(1, 7, std::random_device()());
RandomIterator secondRandom(6, 7);
printAll(firstRandom, secondRandom);
return 0;
}
Mencoba menerapkan operator kurung siku yang melakukan sesuatu yang mirip dengan iterator ini akan dibuat-buat, sedangkan implementasi iterator relatif sederhana. Operator kurung kotak juga membuat implikasi tentang kemampuan kelas Anda - yang dapat Anda indeks ke titik sembarang - yang mungkin sulit atau tidak efisien untuk diterapkan.
Iterator juga cocok untuk dekorasi . Orang-orang dapat menulis iterator yang mengambil iterator di konstruktor mereka dan memperluas fungsinya:
template<class InputIterator, typename T>
class FilterIterator
{
private:
InputIterator internalIterator;
public:
FilterIterator(const InputIterator &iterator):
internalIterator(iterator)
{
}
virtual bool condition(T) = 0;
FilterIterator<InputIterator, T>& operator++()
{
do {
++(internalIterator);
} while (!condition(*internalIterator));
return *this;
}
T operator*()
{
// Needed for the first result
if (!condition(*internalIterator))
++(*this);
return *internalIterator;
}
virtual bool operator!=(const FilterIterator& that) const
{
return internalIterator != that.internalIterator;
}
};
template <class InputIterator>
class EvenIterator : public FilterIterator<InputIterator, std::uint_fast32_t>
{
public:
EvenIterator(const InputIterator &internalIterator) :
FilterIterator<InputIterator, std::uint_fast32_t>(internalIterator)
{
}
bool condition(std::uint_fast32_t n)
{
return !(n % 2);
}
};
int main()
{
// Rolls a d20 until a 20 is rolled and discards odd rolls
EvenIterator<RandomIterator> firstRandom(RandomIterator(1, 21, std::random_device()()));
EvenIterator<RandomIterator> secondRandom(RandomIterator(20, 21));
printAll(firstRandom, secondRandom);
return 0;
}
Walaupun mainan ini mungkin tampak biasa, tidak sulit untuk membayangkan menggunakan iterator dan dekorator iterator untuk melakukan hal-hal yang kuat dengan antarmuka yang sederhana - menghias iterator hasil-hasil basis data hanya-maju dengan iterator yang membangun objek model dari hasil tunggal, misalnya . Pola-pola ini memungkinkan iterasi yang efisien-memori dari set yang tak terbatas dan, dengan filter seperti yang saya tulis di atas, berpotensi hasil evaluasi malas.
Bagian dari kekuatan template C ++ adalah antarmuka iterator Anda, ketika diterapkan pada orang-orang seperti array C panjang-tetap, meluruh ke aritmatika pointer sederhana dan efisien , menjadikannya abstraksi yang benar-benar nol biaya.
some_iterator++
ke++some_iterator
. Pasca-kenaikan menciptakan iterator sementara yang tidak perlu.