Greetings. I'm very glad that websites like this exist, and that domain experts such as yourselves take the time to answer Very Dumb Questions such as this one for people such as myself.
It's my understanding that iterators are one of the fundamental constructs of C++. Things I've read suggest that there are essentially three things that can, and should, be passed around: functions, simple variables, and iterators.
Iterators reference a container structure filled with interesting data, and have two boundaries, a beginning and an end, and offer the ability to easily perform an operation over the span of elements between the two. The beginning boundary is found with a method called
begin
, and the ending boundary is found with a method called
end
; these methods return something called iterator objects [terminology?], which have, among other things (which other things?), a reference to the relevant container, and a pointer to the "current" element in the container between the boundaries.
Iterators have three fundamental operations: a dereference operator (
operator*()
), an equality operator (
operator!=()
), and an incremental operator (
operator++()
). (Assuming that an instantiated operator [terminology?] is named
ite
, the latter operator accommodates only the
++ite
, but doesn't include the
ite++
operation, which as a quirk of C++ is covered by the
operator++(int x)
operator method overload [terminology?].)
Suppose that I have a container that I wish to iterate over. Normally, it seems, it would be sufficient to expose the underlying iterator mechanism of the "child" container, but in this case the container has no native iterator.
Suppose that this container is a bitset of fixed size, e.g.,
std::bitset<9> set("111111111");
,
std::bitset<9> set("110110101");
,
or
std::bitset<9> set("110100011");
,
and the bit positions are related to the sequential values as follows:
987654321
,
and I would like to iterate over this bitset with a range-based for-loop, e.g.,
1 2 3
|
for (auto b : B) {
std::cout << b;
} std::cout << std::endl;
|
,
which should produce, for the latter bitset example above, the output
12689\n
.
As I understand it, I need to construct two classes, one a "parent" container of the bitset, with various attributes, including things to make it recognizable as compatible with iterator operations, including but not limited to the
begin()
and
end()
methods; and one an "iterator" class, which will, among other things, store the current increment of the iterator, and provide various operator overloads [terminology?] such as dereferencing (
uint8_t operator*() { ... }
), equality (
bool operator!=() { ... }
), and incrementation (
SetIter operator++() { ... }
).
Cribbing liberally from the following guide:
https://users.cs.northwestern.edu/~riesbeck/programming/c++/stl-iterator-define.html,
I wrote the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#include <iostream>
#include <bitset>
class SetIter;
class Set {
public:
typedef SetIter iterator;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef uint8_t value_type;
typedef uint8_t * pointer;
typedef uint8_t & reference;
friend class SetIter;
Set(std::string set) : m_set(set) { };
uint8_t at(uint8_t i) { return m_set.test(i); }
SetIter begin() { return SetIter(*this, 0); }
SetIter end() { return SetIter(*this, 9); }
private:
std::bitset<9> m_set;
};
class SetIter {
public:
SetIter(Set &set, int at) : m_set(set), i(at) { };
SetIter operator++() { ++i; return *this; }
uint8_t operator*() { return m_set.at(i); }
void operator!=(Set &cmp_set) { /* ??? */ }
private:
Set m_set;
uint8_t i;
};
int main()
{
Set S("111111111");
}
|
The guide promised that this would work, but it doesn't. I get a number of errors, namely:
1 2 3
|
"forward declaration of 'SetIter'"
"incomplete result type 'SetIter' in function definition"
"invalid use of incomplete type 'SetIter'"
|
So I suspect that
Set
is unable to access the internal structure of
SetIter
, but that's the extent of my understanding the contours of this problem.
And I don't fully understand the implications of the
typedef
s in the definition of
Set
.
Thanks in advance.