Writing Good C++

Yes, C++ is evolving. 🙂 C++14 is almost here and C++17 is rising in the horizon. I find it amazing that so far all attempts to make language somewhat more friendly and safer looked like islands of resistance created by small teams all around the world. And they were disconnected. Coding standards, numerous books on good practices, – we saw them all. We have not seen the C++ father Bjarne Stroustrup saying anything on this subject. I obviously ignoring his book “A Tour of C++” and his conference speeches, but those were conceptually still islands in the ocean. C++ is huge, standard is 300+ pages, last Bjarne’s book is more like a monument to the greatness of C++, but can’t be used neither as a manual nor tutorial.

Here we go. New initiative from The Father to define good practices and guidelines for modern C++.

Here’s his deck from keynote:

https://github.com/isocpp/CppCoreGuidelines/blob/master/talks/Stroustrup%20-%20CppCon%202015%20keynote.pdf

Interestingly, right from the beginning they came up with “good library” called GSL. Static syntax validation tools is coming (good!).

Github link to GSL: https://github.com/Microsoft/GSL

His speech on this subject at CppCon 2015. I like Bjarne’s philosophical view on coding standards. Yes, we hate them! 🙂

C++ STL containers with custom hash function

That’s a bit unusual trip to side roads for me. I’ve been working with C++ for many years and considered myself pretty experienced with STL containers. I remembered (I thought) how to extend a class so. C++ is a language that does not forgive hiatuses. My approach to custom hash function was similar to what highest ranking answer in this stackoverflow answer is showing:

http://stackoverflow.com/questions/647967/how-to-extend-stdtr1hash-for-custom-types

First of all, it’s a bit outdated, because with introduction of C++11 tr1 namespace became obsolete. Secondly, to my shame, I was unable to make my example compile. So after some head scratching, I decided to go for even simpler solution. It may be not as beautiful as what you can find in C++ books, but it works. So here it is.

Our sample class looks like this:

struct Square
{
unsigned long long x;
unsigned long long y;

Square(unsigned long long _x, unsigned long long _y) : x(_x), y(_y) {};
};

To make class work with STL containers like map and set you need to implement a method returning a hash value of the object.

struct SquareHash
{
size_t operator() (const Square& square) const
{
return square.y * 1000 + square.y;
}
};

Besides that you either need to implement a function that compares two values. In case of regular std::map or std::set it should be “<” and in case of unordered_map and unordered_set – “==”. You can do it by implementing an operator< or operator== for operands of your custom class, but I found it even clearer syntactically to implement a class:

struct SquareEqual
{
bool operator() (const Square&amp; lhs, const Square&amp; rhs) const
{
return (lhs.x == rhs.x) &amp;&amp; (lhs.y == rhs.y);
}
};

Just in case, look at unordered_map declaration:

template < class Key, // unordered_map::key_type
class T, // unordered_map::mapped_type
class Hash = hash, // unordered_map::hasher
class Pred = equal_to, // unordered_map::key_equal
class Alloc = allocator < pair<const Key,T> >// unordered_map::allocator_type
class unordered_map;

That’s it! Now you can declare an unordered_map:

unordered_set <Square, SquareHash, SquareEqual> visitedSquares;

Proudly powered by WordPress
Theme: Esquire by Matthew Buchanan.