2

I need to sum up some vectors; that is, I want to sum the nth elements of every vector and make a new vector with the result. (I've already ensured that the input vectors are all the same size.) I'd like to do this with the excellent range-v3 library. I've tried this:

// This file is a "Hello, world!" in C++ language by GCC for wandbox.
#include <iostream>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <map>
#include <range/v3/all.hpp>

int main()
{
   std::cout << "Hello, Wandbox!" << std::endl;

  std::vector< int > v1{ 1,1,1};
  std::vector< int> v2{1,1,1};

  auto va = ranges::view::zip( v1, v2 ) 
    | ranges::view::transform(
      [](auto&& tuple){ return ranges::accumulate( tuple, 0.0 ); }
    );

}

I get the error that I can't call to ranges::accumulate like this. I feel like this is a simple thing that I'm just not quite seeing.

Please advise

EDIT: I ask a follow-on question here: How to zip vector of vector with range-v3

jlconlin
  • 14,206
  • 22
  • 72
  • 105

1 Answers1

2

You can use std::apply to sum over values of a tuple, instead of accumulate:

auto sum_tuple = [](auto&& tuple) { 
  return std::apply([](auto... v) { 
    return (v + ...); 
  }, tuple );
};

auto va = ranges::views::zip( v1, v2 ) 
        | ranges::views::transform(sum_tuple);

Here's a demo. Show's an example with more than 2 vectors as well.

Also, note that ranges::view has been deprecated in favor of ranges::views.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • Using `std::apply` works well. Why doesn't `ranges::accumulate`? (Thanks for the deprecation tip.) – jlconlin May 13 '20 at 22:11
  • `accumulate` needs the range to have `begin`, and `end`, i.e. the input must satisfy the `range` concept. `tuple` doesn't have that interface, so it doesn't satisfy that concept. – cigien May 13 '20 at 22:24
  • Isn't the `tuple` in my example just another `range` since it is the result of `ranges::view::zip`? – jlconlin May 13 '20 at 22:29
  • No, see for example [this](https://github.com/ericniebler/range-v3/blob/master/test/view/zip.cpp#L256). `zip` returns a `tuple`. – cigien May 13 '20 at 22:31
  • Ah, I didn't know it returned a `std::tuple`. I just used `tuple` in my example as an arbitrary name. – jlconlin May 13 '20 at 22:36