C++ Templates
Tags: cpp, codenewbie, beginners
Published: 2021-07-13 21:12:52

In my previous [article](https://codepadawan.hashnode.dev/function-templates-in-c) i wrote on function templates, Now i'm going to be writing on Class templates in C++.
### WHAT ARE CLASS TEMPLATES?###
Class Template can be referred to as blueprints that enable us to create a kind of specialized class with generic constructors, methods, destructors and more. We have a class `Student`:
```C++
class Student{
private:
    std::string temp;
    int data;
public:
    Student(std::string t, int d){
        temp = t;
        data = d;
    }
    int getdata(){
        return data;
   }
   std::string getstring(){
        return temp;
  }
};
```
and we want to model another class that's just like this one but has a `string` and a `double` as it's data members, normally we could just write another class with the same content but with a different name and change the `int` to `double` but that can get tedious and lengthy especially when it's a class with lots of content and it can make your code look unappealing, but class templates make things so much easier because we can write just one class that will serve as a template if we need a similar class, lets do that with the `Student` class:
```C++
#include <iostream>

template<typename S>
class Student{
    template<typename T> //this is for the overloading of the << operator
    friend std::ostream &operator<<(std::ostream &os, const Student<T> &rhs);
private:
    std::string temp;
    S data;
public:
    Student(std::string t, S d){
        temp = t;
        data = d;
    }
    S getdata() const{
        return data;
   }
   std::string getstring() consr{
        return temp;
  }
};
template<typename S> //another template is needed since the ones above can't be reused
std::ostream &operator<<(std::ostream &os, const Student<S> &rhs){
       os << "Name: " << rhs.getstring() << " Data: " << rhs.getdata();
       return os;
}
```
> I overloaded the stream insertion `<<` operator so i can output `Student` objects easier

> I suggest you read the former article on [function templates](https://codepadawan.hashnode.dev/function-templates-in-c) before this one

We create a template parameter `template<typename S>` that will be used to make the `data` attribute in the class able to model any data type, so we replaced the `int` with our template parameter `S` and that's basically it, now we can create a `Student` object that will have the ability to have a `string` with a `double`, `float`, other data types, now we create a `Student` object like this:
```C++
int main(){
    Student<double> padawan{"Padawan", 3.6};
    std::cout << padawan.getdata() << std::endl; //3.6
    Student<std::string> erik{"erik", "human"};
    std::cout << erik.getdata() << std::endl; //human
    Student<Student<int>> casey{"casey", {"glory", 16}};
    std::cout << casey.getstring() << std::endl; // casey
    std::cout << casey.getdata() << std::endl; // Name: glory Data: 16
    //or
    std::cout << casey.getdata().getstring() << std::endl; // glory
    std::cout << casey.getdata().getdata() << std::endl; // 16
    return 0;
}
```
Now you can see how easy it was for me to create a `Student` object that could model a `string` and other data types, you can make the two attributes to be templates, i.e `X temp` and `S data` but you would have to add that to the template parameter `template<typename X, typename S>` so the compiler knows what `X` is. Notice that i even modeled a Student object with a `string` and another `Student` object in it, if you can utilize it these templates properly it can save you writing a lot of unnecessary code, Also the syntax we used in creating these `Student` objects might look familiar to when you create a `vector` object like `std::vector<int> vec{1,2,3};`, that's because vectors too are also template classes behind the scenes, the same goes for other [C++ containers](https://en.cppreference.com/w/cpp/container) like deques, maps, links e.t.c. So that's it, this a just a basic look into class templates, it can get very complex when you mix in stuff like inheritance, polymorphism e.t.c. Here's the source code for what i showed you so far in case you want to copy it into your IDE:
```C++
#include <iostream>

template<typename S>
class Student{
template<typename T>
    friend std::ostream &operator<<(std::ostream &os, const Student<T> &rhs);
private:
    std::string temp;
    S data;
public:
    Student(std::string t, S d) :temp{t}, data{d}{
    }
    S getdata() const{
        return data;
   }
   std::string getstring() const{
        return temp;
  }
};
template<typename S>
std::ostream &operator<<(std::ostream &os, const Student<S> &rhs){
       os << "Name: " << rhs.getstring() << " Data: " << rhs.getdata();
       return os;
}
int main(){
    Student<double> padawan{"Padawan", 3.6};
    std::cout << padawan.getdata() << std::endl; //3.6
    Student<std::string> erik{"erik", "human"};
    std::cout << erik.getdata() << std::endl; //human
    Student<Student<int>> casey{"casey", {"glory", 16}};
    std::cout << casey.getstring() << std::endl; // casey
    std::cout << casey.getdata() << std::endl; // Name: glory Data: 16
    //or
    std::cout << casey.getdata().getstring() << std::endl; // glory
    std::cout << casey.getdata().getdata() << std::endl; // 16
    return 0;
}

```