Reputation: 1
I am currently teaching my self/learning about generic programming and how you can use templates
to declare a datatype at run time. I understood the basic example where you can make a variable a template so that you can make any data type later on but here is me attempting templates with a class/vector:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
template <class T, class U>
class CMap{
private:
vector<T> keys;
vector<U> values;
public:
void insert(T key, U value){
keys.push_back(key);
values.push_back(value);
}
void get(int n){
cout << keys[n] << " values ->" << values[n];
}
};
int main(){
CMap<string, int> grades;
grades.insert("Jones", 12);
grades.insert("Smith", 40);
grades.get(0);
cout << endl;
grades.get(1);
cout << endl;
}
I understand that we created T
and U
as a template which will go into the vector
data type. I also understand we can use the insert
method dynamically because the T
and U
are templates.
What I don't understand:
When I declare my class i have been told to add the following <string, int>
I don't understand what this is doing? How does it know that the first parameter should go to vector<t> keys
and the second parameter inside the <>
should go to vector<u> values
- if that is what it is doing?
Upvotes: 0
Views: 84
Reputation: 21130
Let's first clear up what it means to declare a template in C++, as there seems to be some confusion.
A template is something you create a class out of, sort of like a class factory. A template is not a class nor a type.
You declare a template and the parameters it will take by template<class T, class U /* ... */>
, similar to how a function takes values as arguments.
When you pass in types as template arguments, you instantiate the template, thereby creating a type. When a template is instantiated, the type you passed in will replace the occurrences of the same parameter, again, similar to how argument passing works with functions.
template<class T>
class MyTemplateClass
{
public:
T member;
};
MyTemplateClass<int> var;
In this example MyTemplateClass
is the template, it is not a type.
MyTemplateClass<int>
is a type, having exactly one member variable of type int
. We say MyTemplateClass<int>
is an instantiation of MyTemplateClass
. Every occurrence of T
in MyTemplateClass
is replaced with int
in MyTemplateClass<int>
.
Since MyTemplateClass<int>
is just a type, the last line is simply a variable declaration, therefore var
is just a variable of type MyTemplateClass<int>
.
This all happens at compile-time, not run-time.
The compiler knows exactly what MyTemplateClass<int>
is, and it knows exactly what types are in it, and it knows exactly what the code should compile to.
In your case
template<class T, class U>
class CMap{
private:
vector<T> keys;
vector<U> values;
//...
};
is really declaring that you have a template that have 2 parameters, and has 2 member variables. keys
have type vector<T>
where T
is the first template parameter, and values
have type vector<U>
where U
is the second template parameter.
CMap<string, int> grades;
is really declaring a variable grades
with type CMap<string, int>
.
CMap<string, int>
is an instantiation of CMap
with string
and int
as arguments.
grades.keys
have type vector<string>
and grades.values
have type vector<int>
.
Upvotes: 0
Reputation: 125
When you use the statement CMap<string, int> grades;
you are creating the object of type CMap where each occurrence of T
gets replaced with string
and each occurrence of U
is replaced with int
.
Since your insert method has the signature void insert(T key, U value)
, your newly created object will take in a string
and an int
to replace T
and U
because that's the data type you supplied when creating the object.
You could use whatever data type you like for T
and U
including your own classes.
Upvotes: 1