Generics With C++
Brief Overview
One of the most useful features in Swift is the language support for generics. Recently I’ve been programming with C++ so I want to explore the concepts around generic classes in the language. Generics in C++ can be implemented for classes or functionality. In this example I’m going to stick with C++ class templates, but the ideas behind both of them and the way you go about implementing them are almost identical. Also, I’m not going to dive deeply into template specialization, but I want to note, you can be more specific in how you want to handle a particular type of data, much like the where specifier in Swift.
At the most basic conceptual level, generics are a way to make code flexible enough to accommodate a variety of data input types. Generics abstract the concepts of data types to their most basic form. raywenderlich.com has one of the more elegant definitions for generic programming that I’ve come across:
Generic programming is a way to write functions and data types while making minimal assumptions about the type of data being used.
Getting Started
Let’s break it down in a more concrete way. Say you want to iterate over an array of numbers and perform a function with each element like print:
Now imagine if your program needs to do this over and over for many different arrays at various points throughout your application. Writing five lines each time would quickly become tedious. It could also degrade the readability of your code. To fix this we could create a helper function like this:
This a bit more convenient. We can now print all the values in an array and get the item count using one line. Even so, we’re still tying it to specific data type. We can still do better.
Keeping DRY
Imagine we had arrays all over our project and the array held different types of data. If we wanted to to iterate for an array that held non-integer data types we would have to copy and paste this code and change the input type. This will quickly become the downfall of any effort to keep your code DRY (Don’t Repeat Yourself).
Templates
C++ implements generic programming concepts through templates. Templates give the compiler a framework to generate code for the types it gets implemented with. With a class, C++ will look at your template as well as the type specified when you created the object, and generate that typed class for you.
Think of it as a cookie cutter in the shape of a star. You can have various kinds of cookie dough, like shortbread, or chocolate-shortbread or chocolate chip cookie dough. The cookie cutter doesn’t care about the ingredients, as long as it is dough.
Linked Lists
To prove the power of generics, let’s build a doubly linked list. If you’re new to linked lists, they are data types where each element hold a pointer to the element directly before and after it. A linked list will terminate when the pointer becomes NULL.
If you were using several linked lists with with different data types this could quickly degenerate into messy spaghetti code.
Let’s Be Generic!
To simplify, let’s change a few aspects of the code to make it compatible with generic data types:
We specify template <class T> at the top giving with generic type T. This T could eventually be implemented as char type like:
Linked_List<char> *generic_linked_list = new Linked_List<char>();
Or an int type:
Linked_List<int> *generic_int_linked_list = new Linked_List<int>();
Ultimately, generics are another tool which you can use to make to code more maintainable because they help distill essential functionality and promote readability. At the end of the day, it doesn’t make a huge amount of difference to the compiler whether you copied and pasted functionality all over your code or whether you use generics. Code is meant to be read by people.