Templates and Iterators

Write a text-based war-game in C++arrow-up-right

Template Functions

#include <iostream>
using namespace std;

template <typename T>
void myPrint(T val){
    cout << val << endl;
}

int main() {
    myPrint<int>(5);
    myPrint("hello world");
    myPrint(10.5f);
    return 0;
}
5
hello world
10.5

When the compiler encounters this call to a template function, it uses the template to automatically generate a function replacing each appearance of T by the type passed as the actual template parameter (int in this case) and then calls it. This process is automatically performed by the compiler and is invisible to the programmer.

So myPrint(10.5f) creates void myPrint(float val){...}

Important: T is just the name of the placeholder we could have called it U or something else.

When you design or use a template you should be aware of what operations the data types you will use need to support.

Show this using MSVC in compiler explorerarrow-up-right not the same on clang

Another simple example

T is always the same type T GetMax (T a, T b) so if a is an int, b is also an int.

2 different types

Even though -10.5 is smaller it was casted into T or an int since getMin returns T the first argument

Template Classes

Templates and header files

When you instantiate such a template class, e.g. MyTemplate<int>, the compiler creates the class on the spot. In order to create it, it has to see all the templated member functions (so that it can use the templates to create actual member functions such as MyTemplate::foo() ), and therefore these templated member functions must be in the header.

If the members are not in the header, the compiler will simply assume that they exist somewhere else and just create actual function declarations from the templated function declarations, and this gives you linker errors.

Creditsarrow-up-right

Won't compile! We need to put the template in the header file

2 ways to go around this

1st way

We can include the cpp file in our header file like this

notice the #include "Foo.cpp" at the end of our .h file.

2nd way

or we can explicitly instantiate the template

Here is the important part

Matrix Example

Iterators

Iterator: An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range.

We can dereference iterators like pointers

So aren't iterators basically pointers?

POINTERS

ITERATORS

A pointer hold an address in memory.

An iterator may hold a pointer, but it may be something much more complex. For example, an iterator can iterate over data that’s on file system, spread across many machines, or generated locally in a programmatic fashion. A good example is an iterator over linked list, the iterator will move through elements that are at nodes in the list whose addresses in RAM may be scattered

We can perform simple arithmetic on pointers like increment, decrement, add an integer etc.

Not all iterators allow these operations, e.g., we cannot decrement a forward-iterator, or add an integer to a nonrandom-access iterator.

A pointer of type T* can point to any type T object.

An iterator is more restricted, e.g., a vector::iterator can only refer to doubles that are inside a vector container.

We can delete a pointer using delete

Since an iterator refers to objects in a container, unlike pointers, there’s no concept of delete for an iterator. (The container is responsible for memory management.)

Creditsarrow-up-right

Vector Example

overview of what we want

  • begin() and end() belong to the Vector class

  • operator!= to check that the iterator din't end up at iter.end

  • operator++ increment iterator to point to the next value

  • operator* access the iterator values

Lets Start!!!

Lets see how cool this code really is :)

Lets add some functionality.

  • This will copy from one vector to another Vector<Point> vec2(vector.begin(),vector.end());

  • or basically Vector(Vector<T>::Iterator begin, Vector<T>::Iterator end);

And now

Making our own count_if

count_if - receives the beggining and the end iterators. Additionaly we give it a predicate or Struct with an overloaded parathesis operator.

Try to implement the following functions: any_of -> returns bool if some is true

Last updated