Aku
Aku

Reputation: 200

Iterators and STL containers

I need to make some specific constructor which gets two iterators: start iterator and end iterator.

I have some code and its works:

#include <iostream>
#include <vector>

using namespace std;

template<typename T>
class A
{
public:
    T a[10];
    typename std::vector<T>::iterator itStart, itEnd;
    A(typename vector<T>::iterator itStart, typename vector<T>::iterator itEnd):itStart(itStart),itEnd(itEnd){}

    void see()
    {
        int i=0;
        while(itStart != itEnd)
        {
            cout<<*itStart<<endl;
            a[i] = *itStart;
            itStart++;
            i++;
        }
    }
};

template <typename Iterator>
double Sum( Iterator begin, Iterator end );

int main()
{
    cout << "Hello world!" << endl;
    vector<int> v;
    v.push_back(1);
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);


    class A<int> a(v.begin(),v.end());
    a.see();
    return 0;
}

But I want to make constructor arguments work with all STL containers(like Set,List,Map etc.) and with normal arrays(normal pointers). So can I make it in generic template way? Something like that:

template<typename T>
class A
{
public:
    iterator<T> itStart, itEnd;
    A(iterator<T> itStart, iterator<T> itEnd):itStart(itStart),itEnd(itEnd){}

    void see()
    {
        while(itStart != itEnd)
        {
            cout<<*itStart<<endl;
            itStart++;
        }
    }
};

I know code the above is wrong but I want to explain my idea.

Of course I can overload constructor but I am too lazy to that. Too many STL containers. Is some template way to solve that issue?

Upvotes: 2

Views: 317

Answers (3)

rohitsan
rohitsan

Reputation: 1041

Perhaps you could make use of the notion of an input sequence (iseq).

An input sequence is denoted by a pair of iterators (begin and end).

Of course, you would need to create overloads of all the STL algorithms that accept an iseq instead of a pair of iterators.

Then your example could just use for_each (overloaded to accept an iseq).

Example code can be found in TC++PL 3rd edition (Stroustrup) section 18.3.1.

Upvotes: 0

masoud
masoud

Reputation: 56549

Looking at one of STL's things such as std::fill:

template< class ForwardIt, class T >
void fill( ForwardIt first, ForwardIt last, const T& value );

we can be inspired:

template<typename ITR, typename T>
class A
{
  A(ITR itStart, ITR itEnd):itStart(itStart),itEnd(itEnd){}
  ...

Upvotes: 0

Armen Tsirunyan
Armen Tsirunyan

Reputation: 133122

Obviously you need to make the iterator type a template argument to your class

template<class T, class Iter>
class A
{
   Iter first, last;
   A(Iter first, iter last):first(first), last(last){}
};

But now it becomes uncomfortable to explicitly specify the template argument

A<int, vector<int>::iterator > a;

To avoid that, simply create a factory function

   template<class T, class Iter>
   A<T, Iter> make_A(Iter first, iter last)
   {
       return A<T, Iter>(first, last);  
   }

Now, instead of directly creating an object of A, you can use the function

   auto my_A =  make_A<int>(v.begin(), v.end());

Upvotes: 1

Related Questions