Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrap STL vector and change behavior of its iterator

Tags:

c++

stl

There is such code:

#include <iostream>
#include <vector>

template <class T>
class A{
public:   
    class iterator : public  std::vector<T>::iterator{
    public:
        T& operator*(){
            ??
        }
    };

    iterator begin(){
        return v.begin(); // error
    }

    iterator end(){
        return v.end(); // error
    }

    void add(const T& elem){
        v.push_back(elem);
    }

private:
    std::vector<T> v;
};

int main() {
    A<int> a;
    a.add(2);
    a.add(4);
    for(A<int>::iterator it = a.begin(); it != a.end(); ++it){
        std::cout << *it << std::endl;
    }
    return 0;
} 

This is a wrapper for std::vector with my own additional functions. I would like to use std::vector's iterator, however I want only to change behavior of operator* for iterator:

T& operator*(){
  // do some additional function
  // normal behavior, return value of some element in vector
            ??
}

How can I use std::vector and its iterator with modification of only operator*? I would like also to wrap functions like begin() and end() for iterator, how to wrap them properly?

EDIT:

Using tips from answers in this topic, I managed to solve my problem in following way:

#include <iostream>
#include <vector>

template <class T>
class A {
public:

    class iterator : public std::vector<T>::iterator {
    public:

        iterator(typename std::vector<T>::iterator c) : std::vector<T>::iterator(c) {
        }

        T& operator*() {
            std::cout << "Im overloaded operator*\n";
            return std::vector<T>::iterator::operator *();
        }
    };

    iterator begin() {
        return iterator(v.begin());
    }

    iterator end() {
        return iterator(v.end());
    }

    void add(const T& elem) {
        v.push_back(elem);
    }

private:
    std::vector<T> v;
};

int main() {
    A<int> a;
    a.add(2);
    a.add(4);

    for (A<int>::iterator it = a.begin(); it != a.end() ; ++it) {
        std::cout << *it << std::endl;
    }
    return 0;
} 

Maybe it will be helpful for someone.

like image 998
scdmb Avatar asked Oct 19 '11 15:10

scdmb


People also ask

How do you increment a vector iterator?

If iter is an InputIterator, you can use: ++iter and iter++ to increment it, i.e., advance the pointer to the next element.

Which of the following STL function returns an iterator?

end(): The end() function returns an iterator pointing to the past-the-last element of the container.

How do you access a vector element with iterator?

Use an iteratorvector<int>::iterator iter; An iterator is used as a pointer to iterate through a sequence such as a string or vector . The pointer can then be incremented to access the next element in the sequence. To access the value in the memory space to which the iterator is pointing, you must use * .

How do I move the iterator forward?

Forward iterator use only increments operator (++) to move through all the elements of a container. Therefore, we can say that the forward iterator can only move forward.


1 Answers

Wrapping stdlib iterators is done best with iterator adaptors. This task is far from trivial and there is the Boost.Iterator library to simplify the task. Maybe one of the provided iterators already solves your problem.

If you are going to write this on your own (I really don't recommend this), you should implement your own iterator and have it be constructible from a vector::iterator, then overload all required operators to meet the requirements of the concept that your new iterator models. Also inherit from std::iterator to get the traits working. Don't forget to have the a const variant. This book has a chapter devoted to developing your own iterators. Also get a copy of the standard (C++03 or C++11, doesn't matter much here). You are going to need it.

like image 149
pmr Avatar answered Oct 08 '22 23:10

pmr