Reputation: 500
I have a class containing a map
that stores vectors of shared_ptr
objects.
#include <map>
#include <memory>
#include <vector>
template <class T, class U>
class MyMap {
public:
typedef std::shared_ptr<U> UPtr;
typedef std::vector<UPtr> UPtrVec;
typedef std::map<T, UPtrVec> VecMap;
...
private:
VecMap vec_map;
};
Is it possible to create an iterator (using boost, I presume) for the values inside each mapped vector value? I would also like to be able to iterate over the stored values for a specified list of keys.
For example, if my map contained data like this (switching to Python syntax for brevity)
// note: in actuality the vector contents are shared_ptr's to objects
vec_map[5] = ["one", "two", "three"]
vec_map[8] = ["four", "five"]
vec_map[3] = ["six", "seven", "eight", "nine"]
Is it possible to write an iterator interface such that I could do the following:
MyMap<int, std::string> mymap
...
for(auto it = mymap.begin(), it != mymap.end(); ++it)
cout << *it << " ";
and have it output "one two three four five six seven eight nine" ? If I could get that to work, I'd like to write an iterator that would filter based on key values.
Barring that I was think about creating another UPtrVec
in the class that stored all UPtr
objects in a flat list. But I lose the mapping that would allow me to filter based on key values, unless I embed the key info into the U
objects.
Upvotes: 0
Views: 864
Reputation: 780
You can create your own iterator just using standard C++:
Create a class and inherit if iterator
class using one of the standard iterator tag (input_iterator_tag
, output_iterator_tag
, forward_iterator_tag
, bidirectional_iterator_tag
, random_access_iterator_tag
) depending the type of iterator you want. (input_iterator_tag
is enough for the sample you show).
Implement in that class the iterator interface required by the type. (In cppreference.com you can found the requirements for each iterator).
class MyIterator: public std::iterator<input_iterator_tag, MyClass> {
// requirements for iterators
MyIterator(const MyIterator&);
MyIterator& operator=(const MyIterator&); // or any variant
~MyIterator() noexcept;
MyClass& operator*() const;
MyIterator& operator++();
// requirements for input iterators
MyClass* operator->();
MyIterator operator++(int);
};
// requirements for iterators
bool operator==(const MyIterator& a, const MyIterator& b);
// requirements for input iterators
bool operator!=(const MyIterator& a, const MyIterator& b);
The implemented iterator should have a reference to the used map (or the MyMap
object, depending on how do you implement it), to the vector in the map (for example, using an iterator) and to the element in the vector (again, for example, using an iterator).
Upvotes: 1