From Java to C++ - templates
Tags: cpp, beginners, java, template
Published: 2021-10-14 18:28:25

Generic programming is everyday bread for possibly every Java programmer out there. Only the oldest Java programmers out there still remember the times, when we're casting things all over, and lists were instantiated without explicitly telling the compiler what type of objects they hold. There should be no surprise that the same functionality exists in Java's older cousin - C++.


**DISCLAIMER!** Obviously I'm not an experienced C++ programmer, therefore there's always a possibility, that my knowledge is not enough. I've put a lot of effort, to write this article and make it as good as possible. However, if you think that some concepts or explanations are wrong, please, don't hesitate to point them out! 

**DISCLAIMER 2!** I didn't want to go with full-blown history lesson here. I'm using the latest C++20 standard and all the examples are compiling and working in it. I may indicate once in a while when specific functionality was introduced.


<h2>Let's go</h2>


Generic programming in the C++ is strictly related to the concept of a **template**. Although, in the Java world we're used to the idea of *generics*, **templates** in C++ are a little different, and in my opinion, harder to grasp. In this article, I will try my best, to present generic programming in C++ in a way, that every Java programmer should easily understand. Let's start with a definition of **template**, given by **Stroustrup** himself.

> Basically, a template is a mechanism that allows a programmer to use types as parameters for a class or a function. The compiler then generates a specific class or function when we later provide specific types asarguments.

We can select three separate types of **templates**:
* function templates
* class templates
* variable templates (since C++14)


Additional typology comes with the **template parameters** 
evaluated during compile time), in other words, what can be passed as a parameter to the **template** keyword:


* **param types** - the most common ones, eg. ```template<typename|class T>```
* **none-type parameters** - usually already provided value, eg. number 6. Since C++20 it's also possible to use floating-point numbers and C-style strings (arrays), although with some limitations. However, a lot of other types can be used here as enums, pointers of all kinds or *std::nullptr_t*
* **template-template parameters** - when we inject a template into another template



Here we must remember, that the **T** value, has its own scope, limited to the **template** only!


<h2>Function templates</h2>

This type of template should be very familiar to every Java programmer, as they look and work in the same way as generics in Java. We pass some generic class/type to the function, without any additional assumptions.

```cpp
#include <iostream>
using namespace std;


template <typename T>  // T is usually used to indicate first param, U to indicate second one
T myMax(T x, T y)
{
    return (x > y) ? x: y;
}

// Based on the calls to this function in the main() method
// the template will be replaced with three separate
// implementations of the above method using ints, doubles and    // chars as input params.

int main()
{
    short myShort = 2;
    cout << myMax<int>(3, 7) << endl; // Call myMax for int
    cout << myMax<int>(myShort, 7) << endl; // ERROR - this won't compile as the params are not of the same type 
    cout << myMax<double>(3.0, 7.0) << endl; // call myMax for double
    cout << myMax<char>('g', 'e') << endl; // call myMax for char
    
    return 0;
}
```


First thing to start with is - above **template** is just a recipe for creating concrete **function definitions**. The process of that creation is called **template instantiation**.

Second thing to discuss is whether we should use *typename* or *class* in the **template** definition. Well, as far as I've read, it does not matter that much (especially in C++20). Before the usages were somehow limited when **template templates** were involved. More on that <a href="https://newbedev.
com/difference-of-keywords-typename-and-class-in-templates">can be found here</a>.

Third important concept is - there's no implicit conversion, when we're using **templates**! That's why in the above example the line using *short* variable failed miserably. In our case **template** expects both arguments to be the same type, and that's it. No exceptions!

To overcome the above limitation is to use **explicit template argument specification** (yeah, I know, long name). It is an actual hint to the compiler what will be the type of the used variable. Let's take a look at this example.

```cpp
template<class T1, class T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data)
{}

// This
PrintNumbers(10, 100);    // int, int
PrintNumbers(14, 14.5);   // int, double
PrintNumbers(59.66, 150); // double, int

// Can be changed to use this - and therefore limiting
// the generated specialized versions to only double one
PrintNumbers<double, double>(10, 100);    // int, int
PrintNumbers<double, double>(14, 14.5);   // int, double
PrintNumbers<double, double>(59.66, 150); // double, int

// Generated specialised version
void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
{}
```

This technique should also be used, when there's no way to figure out the type used from the params of the constructor or the methods. Consider this snippet of code:


```cpp
template<class T>
void PrintSize()
{
    cout << "Size of this type:" << sizeof(T);
}

// Calling it like this will cause compiler error
PrintSize();

// But with this - it's working
PrintSize<float>();
```

Going back to the properties of **function templates** - third thing to mention is that **function templates** can be only put into global namespace. There's no way to restrict their visibility to specified scope.


I've mentioned in the comments to the code above, that the compiler will create an actual code for every **function template** that's used in the code. However, there's a possibility to provide our own implementation of these functions if we want to (kind-of like default methods in Java interfaces). Take a look at the following code:

```cpp
#include <iostream>
using namespace std;


template <typename T>
T myMax(T x, T y)
{
    cout << "Inside template implementation: ";
    return (x > y) ? x: y;
}

template<>
short myMax(short x, short y)
{
    cout << "Inside short implementation: ";
    return (x > y) ? x: y;
}

int main()
{
    cout << myMax((short)3, (short)7 ) << "\n" << endl; // Call myMax for short
    cout << myMax(3, 7) << "\n" << endl; // Call myMax for int
    cout << myMax(3.0, 7.0) << "\n" << endl; // call myMax for double
    cout << myMax('g', 'e') << "\n" << endl; // call myMax for char

    return 0;
}
```

Above technique is called **specialization**, and can be applied to every **function template**.

At the end of this section, it's worth mentioning, that there's a possibility to indicate to the compiler, which generated method should be called. I think that the following example will show what I mean.

```cpp
template<class T, class U = char>
class A  {
    public:
        T x;
        U y;
        A() {   cout<<"Constructor Called"<<endl;   }
};

int main()  {
    A<char> a;  // This will call A<char, char>
    return 0;
}
```

The output will be:

<pre>
Constructor Called
</pre>



<h2>Class templates</h2>

**Class templates** are working in a very similar way to the **function templates**, although they are defined at the class level (thank you, Captain Obvious!). As an additional point, there's a possibility to implement them on a class methods **outside** of the class body (this technique applies also to the definition of 'normal' functions). The only thing we have to do while implementing method outside the class, is to prefix the function with a class name. Here's an example:


```cpp
#include<iostream>
using namespace std;


template <typename T>
class MyClass
{
public:
    MyClass(T x, T y)
    {
        cout << "My class constructor: " + to_string(x) + " " + to_string(y) + "\n";
    }

    T myMethodOutsideOfClass();
};

template<typename T>
T MyClass<T>::myMethodOutsideOfClass()
{
    cout << "Inside short implementation \n";
    return 0;
}

int main()
{
    MyClass<int> myClass(1,2);
    myClass.myMethodOutsideOfClass();
    return 0;
}
```


> **HINT!** As a Java guy I was wondering - what's the reason to define function outside the class? It's stupid and puts the class logic in two different places. Well, you are right, it is. However, coming from Java we're used to the fact, that out JARs are packed with both interfaces and implementations. In C++ (and in C), there's this whole concept of dynamic/static libraries, and a possibility to separate interface of the class using **header files**, and use only them during work/writing code. If we put the whole logic inside a class (while it serves also as an interface), with every change in the implementation, we got to recompile the code. With clear separation of class **declaration** from its **definition** - we don't have to. Check out <a href="https://stackoverflow.com/questions/28642430/what-is-the-point-of-defining-methods-outside-of-a-class-in-c">this SO question</a> for more.

> There's one catch in the above - the implementation of the template must still be available to the compiler at the time of header processing! That's why in a multi-file projects, if we want to expose a header with class declaration, all the template-using functions must also be put in the same file!


When it comes to **class templates**, we don't need to operate only on the class level. There's also a possibility to introduce another templating solution which it called **method template** (pay attention to the word **method**, not **function**). I think that the code will explain it best.


```cpp
#include<iostream>
using namespace std;


template <typename T>
class MyClass
{
    public:
    MyClass(T x, T y)
    {
        cout << "My class constructor: " + to_string(x) + " " + to_string(y) + "\n";
    }

    template<typename U>
    void myMethodOfClass(const U& arg)
    {
        cout << "Passed arg: " + to_string(arg) + "\n";
    }
};

int main()
{
    MyClass<int> myClass(1,2);
    myClass.myMethodOfClass(5);
    myClass.myMethodOfClass(2.0f);
    return 0;
}
```


As we're in the object-oriented language (more or less), we have to talk a little about inheritance too. In general, there's no problem with inheriting **class templates**. The only limitation here, is that we have to explicitly tell the compiler, when we want to use base-class functionality. As usual, here's the code:


```cpp
#include<iostream>
using namespace std;

template<typename T>
class Foo
{
public:
    void Func() {}
};

template<typename T>
class Bar : public Foo<T>
{
public:
    void BarFunc()
    {
        // Func();   This causes compilation error
        this->Func();
        Foo<T>::Func();
    }
};

int main()
{
    Bar<int> b{};
    b.BarFunc();
}
```


<h2>Alias templates</h2>

We already saw that **templates** are great tool to reduce code size. There's another way in which **templates** can be useful this way - **alias templates**. As usual, the best way to describe this functionality is with the simple code snippet:


```cpp
template <typename T, int Line, int Col>
class Matrix {
....
};

template <typename T, int Line>
using Square = Matrix<T, Line, Line>;    // That's the alias

template <typename T, int Line>
using Vector = Matrix<T, Line, 1>; 

// Code that uses above constructions
Matrix<int, 5, 3> ma;
Square<double, 4> sq;
Vector<char, 5> vec;
```


The solution is clear and readable. **HINT!** The idea of *aliasing* is not only related to the **templates**! It can be applied to any other type/definition!


<h2>Variable/Variadic templates</h2>


For Java programmers the concept should be pretty familiar - *varargs* used in the templates. That's it. In C++ this vararg is called **template parameter pack**, when used in the **template**, and **function parameter pack**. Here's the code:

```cpp
// Args as a type/name is completely arbitrary and can be anything
template<typename... Args>  // this is for the template

void printMyParams(Args... args)  // this is for the function
```


I don't want to dive into the concept of **parameter pack** right now. The best resource to get an understanding how it works <a href="https://www.modernescpp.com/index.php/component/content/article/55-blog/templates/577-variadic-templates-or-the-power-of-three-dots?Itemid=239">can be found here</a>.
What I want to show is to how can they be used in the **templates**.

```cpp
#include<iostream>

template <typename T, typename... Args>
T sum(T t, Args... args) {
    // [if constexpr] is evaluated during compile time
    // sizeof... is a special operator to determine the amount of params passed
    if constexpr(sizeof...(args) > 0) {  
        return t + sum(args...);
    }

    return t;
}

int main()
{
    std::cout << sum(1,2,3);
}
```


Executing this program will result in printed 6. In order for our example to work, an implementation of ```cppdouble sum(T t)``` should be provided. We avoid the need for that, by checking the amount of variable params passed to the function. As long as it is more than 0, we recursively call the function. If there's no additional params to sum, we just return the passed value. Here is the code with a separate function written.

```cpp
#include<iostream>

template<typename T>
T sum(T t)
{
    return t;
}

template<typename T, typename... Args>
T sum(T t, Args... args) {
    return t + sum(args...);
}

int main()
{
    std::cout << sum(1,2,3);
}
```


To sum up the presentation of **parameter packs**, I'll show something, that is available since C++17 - **folding** (concept known from the functional languages) - if you're interested you can read about it <a href="https://en.cppreference.com/w/cpp/language/fold">on the official page</a>.

```cpp
#include<iostream>

template<typename... Args>
auto sum(Args... args) {
    return (... + args);
}

int main()
{
    std::cout << sum(1,2,3);
}
```


<h2>Static template class members</h2>

Every function or class can contain static members. The wide question to ask would be - how do they behave when they're used in the templates? The answer lies in the statement presented in the previous sub-chapter - **templates** are a recipe for creating specific functions or classes. Therefore, for every calculated combination of the types, a separate instance of function/class will be generated by the compiler. Therefore, every instance will have its own, private static member.


<h2>Concepts</h2>

In this article I will just mention them. First - because they deserve more descriptive article, than just subchapter here. Second - it's a new feature, available in C++20. Therefore, it's not widely used yet. In general - in Java we write something like this:

```java
class MyClass<T extends SomeOtherClass>() {
      T someOtherClass;
}
```

At the compilation level we check, whether passed object meets the criteria of <em>extends SomeOtherClass</em>. It's a very powerful tool, and that's why C++ introduced it too. However, as I've said, I will write a separate article later, and link it here.



SOURCES:

* <a href="https://www.youtube.com/watch?v=VNJ4wiuxJM4&list=PLHTh1InhhwT5o3GwbFYy3sR7HDNRA353e&index=6&ab_channel=CppCon">CppCon 2020 'Back to Basis - Templates part 1'</a> talk
* <a href="https://www.youtube.com/watch?v=0dtjDTEE0hQ&list=PLHTh1InhhwT5o3GwbFYy3sR7HDNRA353e&index=7&ab_channel=CppCon">CppCon 2020 'Back to Basis - Templates part 2'</a> talk
* <a href="https://www.youtube.com/watch?v=LMP_sxOaz6g&ab_channel=CppCon">Back to Basics: Function and Class Templates - Dan Saks - CppCon 2019</a>
* **Bjarne Stroustrup** *'Programming Principles and Practice Using C++ 2ed'* book
* **Josh Lospinoso** *‘C++ Crash Course’* book
* <a href="https://www.geeksforgeeks.org/templates-in-c-vs-generics-in-java/">Templates in C++ vs generics in Java</a> article
* <a href="https://newbedev.com/difference-of-keywords-typename-and-class-in-templates">Typename vs class</a>
* <a href="https://www.modernescpp.com/index.php/alias-templates-and-template-parameters">Template params and alias templates</a>
* <a href="https://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part-1">Guide to C++ templates</a>
* <a href="https://www.codingame.com/playgrounds/2205/7-features-of-c17-that-will-simplify-your-code/constexpr-if">Constexpr if explained</a>
* <a href="https://www.modernescpp.com/index.php/component/content/article/55-blog/templates/577-variadic-templates-or-the-power-of-three-dots?Itemid=239">Parameter pack</a>