mfaieghi
mfaieghi

Reputation: 610

Access to iterators of std containers by a template

I want to write a function that takes an std container beginning and ending to add all values in the container to the third argument. For example, if I have

std::vector<int> my_ints{ 1, 2, 3 };
int sum_int = accumulate(my_ints.cbegin(), my_ints.cend(), 10); //should return 16.

I wanted to generalize this function in a way that it can work with any std containers. How can I write a template that can access to the iterators of the elements?

template<typename It, typename T>
T accumulate(It begin, It end, T x)
{
    for (It i = begin; i != end; ++i) 
    {
        x = x + i;
    }
    return x;
}

This is what I have at the moment. But, it does not compile because x and i are not the same type.

Upvotes: 0

Views: 101

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 118077

As Peter mentioned in a comment, you are trying to add the actual iterator to x instead of the value it's pointing at. You need to dereference the iterator to get the value:

template<typename It, typename T>
T accumulate(It begin, It end, T x) {
    // there's no need create a new iterator (i) here, use the one you already have (begin):
    for(; begin != end; ++begin)
        x += *begin; // use * to dereference the iterator
    return x;
}

Upvotes: 0

Rud48
Rud48

Reputation: 1074

You should reach for std::for_each to do this rather than writing your own function. It will accept any container and any range of values.

If you want to write your own the look into the for-range statement:

template <typename C>
auto accumulate(const C& c) {
    typename C::value_type x { };
    for (auto value : c) {
        x += value;
    }
    return x;
}
std::vector<int> my_ints{ 1, 2, 3 };
int sum = accumulate(my_ints);

Upvotes: 1

Related Questions