I'd like some suggestions for the most terse and 'functional' way to gather pairs of successive elements from a vector (1st and 2nd, 3rd and 4th, etc.) using modern C++. Assume the vector is of arbitrary but even length. For the examples I'm pulling together, I'm summing the elements of each pair but that's not the main problem. I should add I'll use STL only, no Boost.
In Python I can zip them into 2-tuples via an iterator with
s = range(1,11)
print([(x + y) for x,y in zip(*[iter(s)] * 2)])
In Perl 5 I can peel off pairs with
use List::Util qw/pairs sum/;
use feature 'say';
@s = 1 .. 10;
say sum @$_ foreach (pairs @s);
In Perl 6 I can shove them two at a time into a block with
my @s = 1 .. 10;
for @s -> $x, $y { say $x + $y; }
and in R I can wrap the vector into a 2-column array and sum the rows with
s <- 1:10
print(apply(matrix(s, ncol=2, byrow=TRUE), 1, sum))
I am not fluent in C++ and my solution uses for(;;)
. That feels too much like C.
#include <iostream>
#include <vector>
#include <numeric> // std::iota
int main() {
std::vector<int> s(10);
std::iota(s.begin(), s.end(), 1);
for (auto p = s.cbegin(); p != s.cend(); p += 2)
std::cout << (*p + *(p + 1)) << std::endl;
}
The output of course should be some variant of
3
7
11
15
19
Using range-v3:
for (auto v : view::iota(1, 11) | view::chunk(2)) {
std::cout << v[0] + v[1] << '\n';
}
Note that chunk(2)
doesn't give you a compile-time-fixed size view, so you can't do:
for (auto [x,y] : view::iota(1, 11) | view::chunk(2)) { ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With