Search code examples
c++stliterator

Calculate the sum between two iterators in STL containers


I am working on a problem in STL containers:

Create a Sum() function that calculates the sum between two iterators. The function then uses the template argument for the iterator type and accepts two iterators, the start and the end

I am trying to write the following code but I am not understanding the problem can anyone help me please .

template <typename type , typename start , typename  end>
double sum(type& t, start& s , end& e) 
{
  typename t::const_iterator i;
  double sum = 0;
  for (i = s  ; i != e; ++i)
    {
      sum+=*i;
    }
  return sum;
}


int main()
{
  //for list 
  list<double> l; //creat a double type list
  l.push_back(10); //pushing data into list l
  l.push_front(11);//pushing data into list l
  l.push_back(9);//pushing data into list l
  l.push_front(12);//pushing data into list l
  l.push_back(8);//pushing data into list l
  list<double>::iterator itlist;

   cout<<"Sum of List L is : "<< sum( itlist , l.begin() , l.end())<<endl;
}

I don't think i am doing correct. i have got many errors. one of my error is:

no instance of overloaded function "sum" matches the argument list -- argument types are: (std::_List_iterator<double>, std::_List_iterator<double>, std::_List_iterator<double>)

Solution

  • There are a number of issues with your code. In this function:

    template <typename type , typename start , typename  end>
    double sum(type& t, start& s , end& e) 
    

    you are taking s and e by reference. But this can't bind to l.begin() or l.end(), since they return r-values.

    Iterators are generally passed around by copy anyway, so you can simply write:

    template <typename type , typename start , typename  end>
    double sum(type& t, start s , end e) 
    

    You also have an issue here:

    typename t::const_iterator i;
    

    You can't do this because t is a variable, not a type.

    However, you don't need to spell out the type of i at all. Instead, you could simply write:

    for (auto i = s  ; i != e; ++i)
    {
      // ...
    }
    

    and let the compiler deduce the type of i.


    In fact, there is no need to pass itlist to your function at all, since all the needed information is in the other arguments. Also, since both arguments have the same type, you only need one template parameter.

    So now your function would simply be

    template <typename iter>    // a single template argument
    double sum(iter s , iter e) // 2 function arguments, both of the same type
    {
      // ...
    }
    

    and you would call it like this:

    sum(l.begin() , l.end())
    

    Here's a demo.