Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterator in C++

I'm trying to create my own translator. It's university work. I need an iterator in my class Translator.

class Translator
{
private:
    map <string,Word> translator;

public:
    class iterator
    {
       friend class Translator;
        private:
            map<string,Word>::iterator itm;

        public:
            iterator operator++();
            pair <string,Word> &operator*();
            bool operator==(const iterator &it)const;
    };
};

I'm trying to overload operator*();

This is the code.

pair <string, Word>& Translator::iterator::operator*()
{
  return (*itm);
}

Error:

invalid initialization of reference of type ‘std::pair<std::basic_string<char>, Word>&’ from expression of type ‘std::pair<const std::basic_string<char>, Word>

like image 425
Maverick94 Avatar asked Dec 02 '14 09:12

Maverick94


People also ask

Why are iterator used?

The iterator is commonly used to loop through the objects of a collection, read them, and remove them.

What is meant by iterator?

An iterator is an object that contains a countable number of values. An iterator is an object that can be iterated upon, meaning that you can traverse through all the values. Technically, in Python, an iterator is an object which implements the iterator protocol, which consist of the methods __iter__() and __next__() .

What is Type iterator?

An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container.

What is the difference between loop and iterator?

In the absence of iterator calls, a loop statement simply executes an infinite loop. The difference between an iterator call and a routine call is that the iterator call "remembers" its state after it yields a value and, on subsequent calls, it simply resumes execution.


2 Answers

The keys of a map are constant, so the value type is pair<const string, Word>.

Some type aliases might make the code friendlier:

typedef map <string,Word> map_type;
typedef map_type::value_type value_type;

value_type &operator*();
like image 130
Mike Seymour Avatar answered Sep 18 '22 22:09

Mike Seymour


It is more a complement than an actual answer but if you want a nice iterator (STL complient) you will also need to add several typedefs, to say for instance the type of your iterator (in your case you have an input iterator). Then you can use your iterator with any stl algorithm which can be very nice. However this can be quite cumbersome.

A very nice approach is using boost facade iterators, you just need to rewrite what is needed that is three methods for an input iterator that specify how to increment, test if two iterators are equals and dereference. Boost is then doing all the dirty work for you and you can then use all stl algorithms with your standard compliant iterators.

Here is an example from the link I gave you :

# include <boost/iterator/iterator_facade.hpp>
# include "node.hpp"
class node_iterator  : public boost::iterator_facade<
    node_iterator
  , node_base
  , boost::forward_traversal_tag
>{
 public:
node_iterator()
  : m_node(0) {}

explicit node_iterator(node_base* p)
  : m_node(p) {}
 private:
friend class boost::iterator_core_access;

void increment() { m_node = m_node->next(); }

bool equal(node_iterator const& other) const
{
    return this->m_node == other.m_node;
}

node_base& dereference() const { return *m_node; }

node_base* m_node;
};
like image 28
geoalgo Avatar answered Sep 16 '22 22:09

geoalgo