You have to provide a begin and end function, both returning a corresponding iterator, which itself implements operators ++, != and *. The begin and end functions can be free-standing or as members.
Start with implementing an iterator which has the behavior you want. You can implement it as a wrapper around a std::vector::iterator to save most of the "core" work.
The following is untested code
Basically, inside class IDMap, add:
class ItemIterator {
// based on vector iterator
std::vector<Item>::iterator i;
public:
ItemIterator(std::vector<Item>::iterator i) : i(i) {}
// incrementing
ItemIterator & operator ++() { ++i; return *this; }
ItemIterator operator ++(int) { const_iterator old(*this); ++(*this); return old; }
// comparison
bool operator!=(const ItemIterator &o) const { return i != o.i; }
// dereferencing
const T & operator*() const { return i->mItem; }
};
using iterator = ItemIterator;
using value_type = T;
ItemIterator begin() const { return ItemIterator(mItems.begin()); }
ItemIterator end() const { return ItemIterator(mItems.end() ); }
If you ever want to support multiple kinds of "special iteration" over your IDMap, like for example also over the indices, or over the "whole" Items, you should wrap everything above in another adaptor. This adaptor can then be accessed with a member method, like .items().
Brief example:
class IDMap {
// (your code)
public:
struct ItemsAdaptor {
// (insert above iterator definition + usings)
ItemsAdaptor(std::vector<Item>::iterator b,
std::vector<Item>::iterator e)
: b{b}, e{e}
{}
ItemIterator begin() const { return b; }
ItemIterator end() const { return e; }
private:
ItemIterator b, e;
};
ItemsAdaptor items() const {
return ItemsAdaptor(mItems.begin(), mItems.end());
}
};
Then, you can write:
IDMap<int> map = ...;
for (int i : map.items()) {
...
}
mItem(args...), writemItem(std::forward<Arguments>(args)...)for "perfect forwarding". And I guess you have similar logic in the implementation ofAddItem.