trainings/AdvancedCppV2/Presentation/templates_class.md

2.8 KiB

Template classes


Template class example

Template classes are as well used to avoid code duplication, as to create so-called meta-programs within them. Here is an example of a simple template class and its usage:

#include <iostream>

template <typename T, typename U>
class SomeClass {
public:
    T getValue() { return value; }
private:
    T value = {};
    U* ptr = nullptr;
};

int main() {
    SomeClass<int, void> sc;
    std::cout << sc.getValue() << std::endl;
    return 0;
}

Template classes in STL

Template classes are heavily used in STL. For example std::vector, std::list and other containers are template classes and if you want to use them, you do it like here:

std::vector<int> v = {1, 2, 3};
std::list<char> l{'c', 'd', 'b'};

Template type deduction for classes (C++17)

Template types can also be automatically deduced by the compiler thanks to... template functions.

The compiler uses class constructors to achieve that.

From C++17 you can write a code like this:

std::vector v = {1, 2, 3};  // std::vector<int> is deduced
std::list l{'c', 'd', 'b'}; // std::list<char> is deduced

That's not gonna work:

// std::vector v1;          // compilation error, vector of what?
// std::vector v2(10)       // compilation error, 10 elements of what?
// clang error: no viable constructor or deduction guide for deduction of
//   template arguments of 'vector'
// g++ error: class template argument deduction failed:
//   no matching function for call to 'vector()'

Exercise - VectorMap

Write a template class VectorMap that represents an over-engineered std::map.

Inside, it should hold 2 std::vectors of the same size, each with different types. The first vector should hold keys, the other one values.

Elements at the same position in both vectors should create a pair like 1 and 'c' below.

VectorMap<int, char> map;
map.insert(1, 'c');
map[1] = 'e';           // replaces value under 1
std::cout << map[1];    // prints 'e'
map.at(2);              // throw std::out_of_range

Implement the mentioned above insert(), operator[], at() methods.

Do not bother about duplicated keys for now. You can also try to implement additional methods from the std::map interface 🙂

Use cppreference.