Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic and efficient way to add two ranges element-wise

Is there any efficient and idiomatic way to perform the following operation?

std::vector<int> a = { 1, 2, 3, 4 };
std::vector<int> b = { 5, 6, 7, 8 };

for (std::size_t i = 0 ; i < a.size() ; ++i)
{
    a[i] += b[i];
}

I am trying to avoid the brackets/index notation and only use iterators in order for the operation to work with any container with forward iterators. I thought of the following solution:

std::vector<int> a = { 1, 2, 3, 4 };
std::vector<int> b = { 5, 6, 7, 8 };

std::transform(a.begin(), a.end(),
               b.begin(),
               a.begin(),
               std::plus<int>());

However, there is the redundancy of a.begin() and I only get to use + and not +=. Is there some algorithm in the standard library that would allow me to use iterators without having any redundancy or do I have to write the full loops by hand?

like image 577
Morwenn Avatar asked Sep 17 '13 18:09

Morwenn


2 Answers

Perhaps something that was intended to become idiomatic, but never quite did:

std::valarray<int> a = { 1, 2, 3, 4 };
std::valarray<int> b = { 5, 6, 7, 8 };

Now you can do these

std::valarray<int> c = a + b; //apply '+' element-wise; store result in c

a += b;  //apply '+=' element-wise 

See the documentation of std::valarray for more details.

like image 145
Jerry Coffin Avatar answered Sep 27 '22 20:09

Jerry Coffin


What's wrong with the redundancy of a.begin()?

If you're not happy with it, just invent your own algorithm: transform_inplace

template <class InputIterator, class OutputIterator, class BinaryOperator>
OutputIterator transform_inplace (InputIterator first,
                                  InputIterator last,
                                  OutputIterator result,
                                  BinaryOperator op)
{
  while (first != last) {
    *result = op(*result, *first);
    ++result; 
    ++first;
  }
  return result;
}
like image 33
Peter Alexander Avatar answered Sep 27 '22 21:09

Peter Alexander