Reputation: 3
I try to write my implementation of c++ iterator, but met some problems. When I try to iterate in range-based for, but get error that my iterator don't have suitable "begin" function and none was found. I wrote begin() and end() function. What's wrong?
#include <iostream>
template<typename T>
class iter final {
private:
T* current_ = nullptr;
T* end_ = nullptr;
int n;
public:
iter(T* first) :current_(first) {};
iter() {};
inline T& operator+ (int n) { return *(current_ - n); }
inline T& operator- (int n) { return *(current_ - n); }
inline T& operator++ (int) { return *current_++; }
inline T& operator-- (int) { return *current_--; }
inline T& operator++ () { return *++current_; }
inline T& operator-- () { return *current_--; }
inline bool operator!= (const iter& it) { return current_ != it.current_; }
inline bool operator== (const iter& it) { return current_ == it.current_; }
inline T& operator* () { return *current_; }
inline iter<T>* begin() { return current_; }
inline iter<T>* end() { return end_ + n; }
inline void set_current(T* _current) { current_ = _current; }
inline void set_end(T* _end) { end_ = _end; n = (end_ - current_) / sizeof(_end); }
inline void set_num(int num) { n = num; }
};
template<typename T>
class shuffle_range final {
public:
shuffle_range() { it = new iter<T>; };
~shuffle_range() { delete it; };
iter<T>* it;
};
template<typename T>
iter<T>* make_shuffle(T* begin, T* end) {
static shuffle_range<T> shuffler;
shuffler.it->set_current(begin);
shuffler.it->set_end(end);
shuffler.it->set_num(end - begin);
return shuffler.it;
}
int main() {
int a[] = { 0, 4, 5, 2, 8, 1 };
auto shuffle_a = make_shuffle(a, (a + 5));
for (auto i : shuffle_a)
std::cout << i << " ";
return 0;
}
Upvotes: 0
Views: 95
Reputation: 3506
For your question - make_shuffle
returns a pointer to iter<T>
class, which means that in order to iterate over this instance, you need to get the pointer value:
for (auto i : *shuffle_a)
std::cout << i << " ";
However, pay attention that you have another issue with your end
function implementation. It checks for end_ + n
instead of end_
or current_ + n
. My suggestion is to get rid from one of them (select which one you use), and use a function to get the other one. For example, you can add size()
member function to get n
:
inline size_t size() { return (end_ - current_) / sizeof(end_); }
Upvotes: 1
Reputation: 2216
A for each loop in C++ is just a masking of the normal for loop which goes from start to end of a given list of objects of the same type. It even gets converted to one. So, in you case, the compiler does not know how to process the for-each loop. It would be better if you instead used a normal for loop. Something like:
for(auto i = shuffle_a.begin(); i != shuffle_a.end(); i++) { //mind well!!! `end()` must return an iterator pointing to the element after the last element
<whatever>
}
will suffice
Upvotes: 1