Use of STL

Rule: Specify comparison types for associative containers of pointers (ES20)

For instance, instead of declaring

using temp_set_type = std::set<const Temp*>;


/// Object function to compare two Temp*.
struct temp_compare
  operator()(const Temp* s1, const Temp* s2) const
    return *s1 < *s2;

using temp_set_type = std::set<const Temp* , temp_compare>;

temp_set_type my_set;

Or, using C++11 lambdas:

/// Lambda to compare two Temp*.
auto temp_compare = [](const Temp* s1, const Temp* s2)
                      return *s1 < *s2;

using temp_set_type = std::set<const Temp* , decltype(temp_compare)>;

temp_set_type my_set{temp_compare};

Scott Meyers mentions several good reasons, but leaves implicit a very important one: if you don’t, since the outputs will be based on the order of the pointers in memory, and since (i) this order may change if your allocation pattern changes and (ii) this order depends of the environment you run, then you cannot compare outputs (including traces). Needless to say that, at least during development, this is a serious misfeature.

Rule: Prefer standard algorithms to hand-written loops (ES43)

Using for_each, find, find_if, transform etc. is preferred over explicit loops. This is for (i) efficiency, (ii) correctness, and (iii) maintainability. Knowing these algorithms is mandatory for who claims to be a C++ programmer.

Rule: Prefer member functions to algorithms with the same names (ES44)

For instance, prefer my_set.find(my_item) to find (my_item, my_set.begin(), my_set.end())}. This is for efficiency: the former has a logarithmic complexity, versus… linear for the latter! You may find the Item 44 of Effective STL on the Internet.