I've had trouble compiling iterator logic in MSVC. It results in a compilation error when trying to express an iteration using the short-hand for (type element: container) { ... }
It could be duplicate but I am unaware what keywords to search for..
Using MSVC 2019, C 17 compilation mode
/// iterator
template <typename T>
struct iter2 {
T *start;
size_t index;
///
void operator () { index ; }
void operator--() { index--; }
///
operator T& () const { return start[index]; }
///
bool operator==(iter2 b) const { return start == b.start && index == b.index; }
bool operator!=(iter2 b) const { return start != b.start || index != b.index; }
/// defined ctr
iter2(T *start, size_t index) : start(start), index(index) { }
};
// a trivial structure.
struct field2 { int key, val; };
///
template <typename T>
struct array2 {
/// just a simple C array
T buffer[100];
int count;
iter2<T> begin() { return iter2<T>(buffer, 0); };
iter2<T> end() { return iter2<T>(buffer, count); };
};
static bool exists(int k) {
/// populate an array with some copied data
field2 f1 = {}, f2 = {};
array2<field2> a;
a.buffer[0] = f1;
a.buffer[1] = f2;
a.count = 2;
/// iterate through as the shorthand for (type element:container) iterate 'should' ?
/// compiles on msvc 2019, c 17
for (iter2<field2> it = a.begin(), e = a.end(); it != e; it) {
field2 &f = (field2 &)it;
if (f.key == k)
return true;
}
/// does not compile, and says:
/// (...,26): error C2100: illegal indirection
for (field2 &f: a) {
if (f.key == k)
return true;
}
return null;
}
int main(int argc, char **argv) {
exists(0);
return 0;
}
CodePudding user response:
Your iter2
type does not satisfy the requirements of an input iterator, as it does not implement operator*
, which a range-for loop uses to access the elements that are being iterated.
You need to add this to iter2
:
T& operator*() { return start[index]; }
And then consider removing operator T&()
, as that is not an operator that an iterator should or need to implement.
And then, in exists()
, you can change your non-range for
loop to use field2 &f = *it;
instead.
On a side note, your pre-increment/decrement operators should return a reference to the iterator that is being updated, eg:
iter2& operator () { index; return *this; }
iter2& operator--() { --index; return *this; }
And, consider adding post-increment/decrement operators, too:
iter2 operator (int) { iter2 temp(*this); index; return temp; }
iter2 operator--(int) { ite2 temp(*this); --index; return temp; }
You might also consider adding an operator->
, too:
T* operator->() { return &start[index]; }