C++ STL Algorithms Series - Part #1

Written By Tom Hulton

Topic

An introduction to why you might want to start using the and header more in your code.

Motivation

There is a growing movement in the C++ community to favor algorithms (usually found in and ) over hand-written loops. There are a multitude of reasons for this (such as correctness, performance, and readability, to start) and it’s a pattern that comes up again and again in other languages too.

Why use these STL templates? Specifically, because you want to move to a more declarative model (and describe what should happen) as opposed to an imperative one (describe how it should happen), which leads to cleaner, easier-to-maintain code and just happens to have the useful bonus of providing well-tested, thread-safe, and performant implementations. Why not use them? Well, it might be because you weren’t aware of them — and that’s why I hope this post can help you!

Before we dive into an example, I want to make an important note: Many of the functions in the header come with a ‘default-op’ (often unfortunately coupled with the name) which makes certain functions easy to overlook – when in fact they’re much more flexible and versatile than one would think.

Example

Say you’d like to quickly count all gadgets with a priority greater than five. Your initial intuition may be to reach for the trusty for loop (made better with the range-based version), but if you see below there’s an alternative that is much more explicit about what it’s doing.

AZStd::vector gadgets;

// loop version
int gadget_count_loop; // must be mutable, booo… :frowning:
for (const Gadget& gadget : gadgets)
{
if (gadget.priority > 5)
{
gadget_count_loop++;
}
}

// algorithm version
const auto gadget_count_algo = // now const and immutable, yay! :slight_smile:
AZStd::count_if(std::begin(gadgets), std::end(gadgets),
[](const auto gadget)
{
return gadget.priority > 5;
});

Deliberation

There is definitely some debate around the verbosity of the calling code. Having to pass a begin and end iterators can be cumbersome (and at times error-prone) and the unfamiliarity can be an initial barrier to entry.

That being said the benefits largely outweigh the costs and with C++ 20 and the addition of ranges, the same algorithms can be used in a much cleaner way, so having existing familiarity with them will be very beneficial. Plus, getting comfortable with STL iterator syntax and semantics is a great investment in becoming a more efficient C++ developer, too!

Further Reading

If you watch one talk about C++ in your lifetime it should probably be this one:

C++ Seasoning, Sean Parent - https://youtu.be/W2tWOdzgXHA

In upcoming posts we’ll have more recommendations that go into much greater detail but this is where it all started.

To be continued…

Next time we’ll explore a few more concrete examples to show where algorithms can really come into their own own and include additional references for more information.

4 Likes