I have the following class declaration:
class Dictionnary{
private:
map< int,list<string> > data;
public:
bool isPrime();
class prime_iterator{
private:
map< int,list<string> >::iterator it;
public:
iterator(){}
prime_iterator & operator++(){
++it;
while(it != data.end() && !isPrime(it->first)){
++it;
}
return it;
}
...
};
which is intended to provide an iterator over prime keys of a map<int,list<string>>
. I'm not sure operator++ is well implemented.
First, is it a good design to do it != data.end()
accessing the outer class? Second, is operator++ returning the right thing or should return only prime_iterator?. Also, can you think about any better solution?
My advice is to always try to find solution elsewhere - if not found - then only create by yourself:
You can use boost::fiter_iterator
For your case it would look in this way:
#include <boost/iterator/filter_iterator.hpp>
using DataMap = std::map<int, std::list<std::string>>;
struct is_prime_number {
bool operator()(const DataMap::value_type& x) { return x.first % 2 == 0; }
}; // I know this is just is_even - not is_prime :D
using DataMapPrimeIter = boost::filter_iterator<is_prime_number, DataMap::iterator>;
inline DataMapPrimeIter only_prime_begin(DataMap& dataMap)
{
return boost::make_filter_iterator<is_prime_number>(dataMap.begin(), dataMap.end());
}
inline DataMapPrimeIter only_prime_end(DataMap& dataMap)
{
return boost::make_filter_iterator<is_prime_number>(dataMap.end(), dataMap.end());
}
And usage:
int main()
{
DataMap dataMap{{1,{"A","B"}}, {2,{"C", "D", "E"}}};
for (auto i = only_prime_begin(dataMap), end = only_prime_end(dataMap); i != end; ++i)
{
std::cout << i->first << i->second.front() << std::endl;
}
}
If you want to have your own implementation, or you cannot use boost in your project - then look at boost implementation - it is for free to look at...