# C++ Templates and the STL

# Templates

A template is essentially a compiler abstraction that allows you to write generic code that applies to various types or classes without concern for the details of the type.

#include <iostream>
#include <string>
using namespace std;

template<typename T>
T maxof (const T & a, const T & b) {
    return (a > b ? a : b);
}

int main() {
    int a = 7;
    int b = 9;

    cout << "max is " << maxof<int>(a, b) << endl;

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
max is 9
1

When the compiler encounters this template, it says okay and it stores it away, and when it encounters the implementation here maxof<int>(a, b), where we call it, it says okay I need a specialization with int in place of T. And then it will create a function called int maxof, const, int, a, const, int, b. Like this.

#include <iostream>
#include <string>
using namespace std;

int maxof(const int & a, const int & b) {
    return (a > b ? a : b);
}

int main() {
    int a = 7;
    int b = 9;

    cout << "max is " << maxof(a, b) << endl;

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

And we build and run, we see it works exactly as expected.

max is 9
1

And so when we have the template function, the compiler it encounters all of this, and it says okay I need a specialization of this template function with int as the type, and it builds this on its own. It built that int specialization.

So if instead of int I were to say const char pointer:

#include <iostream>
#include <string>
using namespace std;

template<typename T>
T maxof (const T & a, const T & b) {
    return (a > b ? a : b);
}

int main() {
    const char * a = "seven";
    const char * b = "nine";

    cout << "max is " << maxof<const char *>(a, b) << endl;

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
max is nine
1

Alphabetically seven is greater than nine.

What's happened is our template specialization is built for the constant character pointer and it's comparing the pointers. It's not comparing what's pointed at. It's not comparing the strings. And if we think about it, that's really what we would expect.

If we use a string type:

#include <iostream>
#include <string>
using namespace std;

template<typename T>
T maxof (const T & a, const T & b) {
    return (a > b ? a : b);
}

int main() {
    string a = "seven";
    string b = "nine";

    cout << "max is " << maxof<string>(a, b) << endl;

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Now we build and run. We get seven, which in alphabetical comparison, seven is greater than nine.

max is seven
1

A template is a compiler abstraction. The compiler creates a specialization for each type, or each combination of types passed to the template.

# Template syntax

The keyword template introduces the template, and type names are listed in the angle brackets, separated by commas, so I can have more than one here.

Though keyword type name or class is interchangeable here, I tend to use type name, others tend to use class, just be consistent. In this case the type name is named T.

The type name T is an alias that will be replaced by the type used in the template

template<typename T>
1

We call the template here with the name of the function, maxof, and we put a type inside angle brackets. This is called the template parameters.

This tells the compiler, remember this is a compiler abstraction, it happens at compile time, so this tells the compiler what sort of specialization to use.

Here a specialization is created for the maxof function using int in place of the type name.

cout << "max is " << maxof<int>(a, b) << endl;
1

So when I run this, it says max is nine, when I compile it, it creates a specialization of the function, using the type int in place of the type name T.

#include <iostream>
#include <string>
using namespace std;

template<typename T>
T maxof (const T & a, const T & b) {
    return (a > b ? a : b);
}

int main() {
    int a = 7;
    int b = 9;

    cout << "max is " << maxof<int>(a, b) << endl;

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
max is 9
1