A rant about C++ containers

I always forget how much I struggle with C++'s patterns for using their data containers. This is how much code you have to write to find the intersection between two sets:

auto intersec = set<int>();
std::set_intersection(lhs.begin(), lhs.end(),
                      rhs.begin(), rhs.end(),
                      std::inserter(intersec, intersec.begin()));

The worst for me is the fact that it would be fairly easy to implement a template that could be called like this:

set<int> intersect = set_intersection(lhs, rhs);

I can go do it myself, but there are a too many of these inconvenient hoop-jumping interfaces to bother writing convenience functions for everything. And it is such a hassle to add external dependencies to a project, that it’s not worth the effort to add some third party convenience functions.

Some of C++'s hoop-jumpings are so familiar that the community even started naming them (like the remove/erase idiom), yet they don’t just implement a convenient function for it in the standard library:


I preferred it more general:

// Erases a specific element from a vector.
template <typename T>
void erase_vector_element(std::vector<T>& vec, T element) {
  vec.erase(std::remove(vec.begin(), vec.end(), element), vec.end());

I found myself rewriting C++ code to use patterns common in Julina like metaprogramming and multiple dispatch, until I realized I don’t need C++ at all.

What always bothered me is existence of dozens different standards which all have their specific quirks with no good reason at all. So even if a modern feature like the one you want was implemented in std in C++14, 17 or 20, you and your collaborators would have hard time getting it to work across different environments.


Many OOP “design patterns” are eliminated by multiple dispatch. This famous presentation is about CL(OS), but pretty much all of it applies to Julia: