++ construction operator to iterate over some animation elements

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 for simple keys map<int,list<string>>. I am not sure if the ++ operator is well implemented.

First, is it a good idea to make it != data.end()access to an outer class? Secondly, the ++ operator returns the right thing, or should it only return prime_iterator ?. Also, can you think of any better solution?

+4
source share
2 answers

My advice is to always try to find a solution elsewhere - if not found - then create it yourself:

you can use boost::fiter_iterator

:

#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());
}

:

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;
    }
}

boost , - - , ...

+1

. typedef .

#include <iterator>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>

typedef std::map<int, std::string> map_t;

class Dictionary {
private:
    map_t& m_map;
public:
    class prime_iterator {
    public:
        prime_iterator( map_t::iterator begin, map_t::iterator end )
            : m_current(begin), m_end(end) {
            runUntilPrime();
        }

        prime_iterator& operator++() {
            m_current++;
            runUntilPrime();
            return *this;
        }

        bool operator != (prime_iterator other) {
            return other.m_current != m_current;
        }

        map_t::value_type& operator* () {
            return *m_current;
        }

    private:
        map_t::iterator m_current;
        map_t::iterator m_end;

        bool isPrime(int x) {
            std::vector<int> primes = { 1, 2, 3, 5, 7, 11, 13, 17 };
            return std::find( primes.begin(), primes.end(), x ) != primes.end();
        }

        void runUntilPrime() {
            while( m_current != m_end && !isPrime(m_current->first) ) {
                m_current++;
            }
        }

    };

    Dictionary( map_t& tmap )
        : m_map(tmap) {}

    prime_iterator begin() {
        return prime_iterator( m_map.begin(), m_map.end() );
    }

    prime_iterator end () {
        return prime_iterator(m_map.end(), m_map.end());
    }

};

int main( int argc, char** argv ) {

    map_t map;

    map.emplace(0, "zero");
    map.emplace(1, "one");
    map.emplace(2, "two");
    map.emplace(3, "three");
    map.emplace(4, "four");
    map.emplace(5, "five");
    map.emplace(6, "six");
    map.emplace(7, "seven");
    map.emplace(8, "eight");
    map.emplace(9, "nine");
    map.emplace(10, "ten");
    map.emplace(13, "thirteen");

    Dictionary dict( map );

    for( auto p : dict ) {
        std::cout << p.first << "\t" << p.second << std::endl;
    }

    return 0;
}
+1

Source: https://habr.com/ru/post/1607068/


All Articles