Hello everybody
So far, we should have a bit idea of templates programming. In this post I'll speak about overloading functions center of attention to templates.
For a change, I follow using max function.
#include <iostream> namespace mySpace{ inline const int& max (const int& a, const int& b){ std::cout << "int"<< std::endl; return a>b?a:b; } template < class T > inline T max (const T& a, const T& b){ std::cout << "template"<< std::endl; return a>b?a:b; } template < class T > inline T max (const T& a, const T& b, const T& c){ std::cout << "template, 3: "<< std::endl; return max(max(a,b),c); } } int main(){ // calls the template with three arguments //and this one will call the non-template int function (by argument deduction) //because the better choise that compiler can make mySpace::max(2, 1, 9); //both types match perfectly, so calls non-template int (by argument deduction) mySpace::max(3, 5); // if the template can generate a better match, will be selected // there is neither a function with char arguments nor template, so // the call will be max<char> (by argument deduction) mySpace::max('a', 'b'); // calls max<double> (by argument deduction) mySpace::max(3.2, 5.4); // forcing the call template with no deduction // calls max<double> (no argument deduction) mySpace::max<double>(7, 42); // calls the nontemplate for two ints mySpace::max('a', 42.7); // calls max<int> (by argument deduction) // with <>, we are calling the template function // rather that a non-template exists mySpace::max<>(7, 42); return 0; }
Up to now it seems easy, what happends wheter we start using pointers and char types.
I like to be practical, so let's see another one:
#include <iostream> #include <cstring> #include <string> namespace mySpace{ template < class T > inline const T& max (const T& a, const T& b){ std::cout << "template"<< std::endl; return a>b?a:b; } template < class T > //I have changed the argument types to constants because I want to pass it by reference, (&) //note that const T& is equivalent to T const& inline T* const& max (T* const& a, T* const& b){ std::cout << "template pointer: "<< std::endl; return a>b?a:b; } //a fuction for C-string, char* /* * Note: Go back and remember the first template max; I didn't * show any call like max("abc","acd"), this one is deduced as * a char*, so, with the implementations we did (return a>b?a:b;), * this operacion is comparing the pointers and no his values * so this was a bug * * In order to resolve it, we may call max<std::string>("abc","acd") * or calling constructor like std::string: max(std::string("abc"),std::st * ring("acd") ) * * Or with the following function */ // inline char const* const& max (char const* const& a, char const* const& b){ std::cout << "c-string: "<< std::endl; return (std::strcmp(a,b) < 0) ? b : a; } } int main(){ int a = 5, b = 10; int* p_a = &a; int* p_b = &b; //pointers_to mySpace::max(a,b); //template mySpace::max(p_a,p_b); //template pointer mySpace::max(*p_a,*p_b); //template char const* s2 = "I'm so cool"; char const* s1 = "David"; mySpace::max(s1,s2); //c-string mySpace::max<>(s1,s2); //template, the output is David, WRONG! mySpace::max("asd","asdasd");//c-string std::string s3 = "David"; std::string s4 = "I'm so cool"; mySpace::max(s3,s4);//c-string //This is more typical in C char* s5 = "David";//warning: deprecated conversion from string constant to ‘char*’ char* s6 = "I'm so cool";//warning: deprecated conversion from string constant to ‘char*’ //warning: deprecated conversion from string constant to ‘char*’ //our function works with char const*, so call templates, //and how templates are constants this make a warning //but note that call can be wrong mySpace::max(s5,s6);//template return 0; }Note that I declared all templates as const and by reference, is a good practice to do unless you need to modify.
That's all today, next I will do a bit example with char const* using 3 parameters, like first exercice.
No comments:
Post a Comment