Usage of STL algorithm functions on more then one dimensional containers

Viewed 101

I have a simple struct

struct Point
{
    Point(int x, int y)
        : x(x)
        , y(y)
    {}
    
    int x, y;
};

And a two dimersional vector(it also can be a three dimensional vector or more)

std::vector<std::vector<Point>> v(10, std::vector<Point>(10, Point(3, 4)));

And I want to know the summary of all x values. I can use std::accumulate and it would look like

int sum = std::accumulate(v.begin(), v.end(), 0, [](int init, const auto& vec)
  {
    return init + std::accumulate(vec.begin(), vec.end(), 0, [](int init, Point p)
    {
        return init + p.x;
    });
  });

or I can write a simple double for

for (const auto& vec : v)
{
    for (const auto& p : vec)
    {
        sum += p.x;
    }
}

And it looks more readable(imo). What should I change to make the usage of std::accumulate has better readability? Or it's not applicable in such case. Is it applicable in general to use STL when you have more then one dimensional container?

1 Answers

If you consider the STL as it stands now, then a nested range-for loop is probably the most readable (though it's still subjective).

However, I am very much an advocate of not using range-for loops, unless you need a transform or a for_each. If the code is doing an accumulate, then you should write an accumulate.

Here's how I would write this code today, with the help of range-v3. Before long, the STL will let you write code that's as readable.

namespace rs = ranges;
namespace rv = ranges::views;

int sum = rs::accumulate(v | rv::join, 0, std::plus{}, &Point::x);

Here's a demo.

Related