Generics in C++

Starting with version 1.18, C++ has added support for templates, which are similar to generics in other languages.

As an example of a template function, SlicesIndex takes a vector of any comparable type and an element of that type and returns the index of the first occurrence of v in s, or -1 if not present. The std::vector and std::equal_to are used to achieve this functionality.

#include <iostream>
#include <vector>
#include <algorithm>

template<typename S, typename E>
int SlicesIndex(const S& s, const E& v) {
    auto it = std::find(s.begin(), s.end(), v);
    if (it != s.end()) {
        return std::distance(s.begin(), it);
    }
    return -1;
}

As an example of a template class, List is a singly-linked list with values of any type.

template<typename T>
class List {
private:
    struct element {
        element* next;
        T val;
        element(const T& v) : next(nullptr), val(v) {}
    };
    element *head, *tail;

public:
    List() : head(nullptr), tail(nullptr) {}

    void Push(const T& v) {
        element* new_elem = new element(v);
        if (tail == nullptr) {
            head = tail = new_elem;
        } else {
            tail->next = new_elem;
            tail = new_elem;
        }
    }

    std::vector<T> AllElements() const {
        std::vector<T> elems;
        for (element* e = head; e != nullptr; e = e->next) {
            elems.push_back(e->val);
        }
        return elems;
    }

    ~List() {
        while (head) {
            element* temp = head;
            head = head->next;
            delete temp;
        }
    }
};

Here’s how we can use these template functions and classes:

int main() {
    std::vector<std::string> s = {"foo", "bar", "zoo"};

    std::cout << "index of zoo: " << SlicesIndex(s, std::string("zoo")) << std::endl;

    List<int> lst;
    lst.Push(10);
    lst.Push(13);
    lst.Push(23);
    std::cout << "list: ";
    for (int val : lst.AllElements()) {
        std::cout << val << " ";
    }
    std::cout << std::endl;

    return 0;
}

When compiling and running this program, you should see:

$ g++ -std=c++17 generics.cpp -o generics
$ ./generics
index of zoo: 2
list: 10 13 23

In C++, templates are a compile-time feature, which means that the compiler generates specialized code for each type the template is used with. This can lead to better performance compared to runtime polymorphism, but it can also increase compile times and code size.