Sunday, February 12, 2012

Why templates?

What is a template?

Template programming is a programming method where we don't indicate what type we are using so this allow to make generals methods or whatever.

For instance, a typical scenario where we can use templates are data structures, such a list or a binary list. We just have indicate what class we are using.



Undestanding its usefulness:

For example:
#include <vector>
class MyClass{};//empty
    
int main(){
    std::vector<MyClass> myVector;
        myVector.push_back(MyClass());
    return 0;
}

In this example we are adding an empty class to a vector (it's a bit stupid, I know), note that this class don't have constructor, C++ makes default.

We can see that vector class is implemented with templates so just putting our class we can use it. Think about it.

Other examples are override methods. C++ allow override methods, for example:

#include <vector>
#include <iostream>
int max (int a, int b){
    std::cout << "max_int" << std::endl;
    return a>b?a:b; 
}
float max (float a, float b){
    std::cout << "max_float" << std::endl;
    return a>b?a:b; 
}
int main(){
    int a = 10, b = 20;
    float c = 10.1, d = 10.2;
    
    std::cout << max(a,b) << std::endl;
    std::cout << max(c,d) << std::endl;
    return 0;
}

Running this returns:


max_int
20
max_float
10.2

So we can see which function have been called.

The next code show a bit how C++ works and some mistakes we can make if we don't know it:

#include <iostream>
bool isMaxA (int a, int b){// if a is maxim return true(1) else return false(0)
    std::cout << "max_int" << std::endl;
    return a>b; 
}

int main(){
    float c = 10.2, d = 10.1;
    
    std::cout << isMaxA(c,d) << std::endl;
    return 0;
}
/*
This program print this:
max_int
0
*/

This isn't the answer we expected. And why is this happening?
C++ try to find a function to call isMaxA where it takes float arguments but cannot so  call isMaxA with int arguments. Transforming float to int ( by trucation ) so out function compares 10>10 and, indeed, the answer is no instead of 10.2>10.1

So with this fool example we can see weaknesses and, in fact, it's a bit stupid to declare two methods that are exacly the same.

Solucion (templates):
#include <iostream>
#include <cstring>
namespace mySpace{ // getting sure that this is the class we call becouse std::max is implemented
    template < class T > // for any class/typename T
    inline const T& max (const T& a, const T& b){ //
        return a>b?a:b; // where the operator '>' is implemented
    }
}
int main(){
    int a = 10, b=20;
    float c = 10.2, d = 10.1;
    std::string e = "a";
    std::string f = "aa";
    
    std::cout << mySpace::max(a,b) << std::endl;
    std::cout << mySpace::max(c,d) << std::endl;
    std::cout << mySpace::max(e,f) << std::endl;
    std::max(a,b);
    return 0;
}


That's all today, I'll explain slowly soon why I have used words like inline, namespace, class, etc
Just get the idea
See you soon



No comments:

Post a Comment