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:

3 Likes

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.

3 Likes

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:

3 Likes