Функциски шаблони

Шаблони во C++ се дефинирани како blueprint /урнек или форма за креирање генеричка класа или функција. Едноставно кажано, можете да креирате една функција или една класа за работа со различни типови на податоци користејќи шаблони.

Шаблоните се една од најмоќните функции во C++. Даваат код кој е независен од типот на податоци. Со други зборови, користејќи шаблони, можеме да напишеме генерички код кој работи на кој било тип на податоци. Треба само да го пренесеме типот на податоци како параметар. Овој параметар кој го пренесува типот на податоци се нарекува и име на тип.

Да го разгледаме следниот пример  :

Програма за наоѓање најголем од три цели броја, три реални броја и три знаци  со користење на функции за преклопување

РЕШЕНИЕ:

1. Може да напишете различни функции за секој тип (int, float, char). Тоа е најлошото решение. 
2. Може да напишете преоптоварени (overloaded) функции за различни параметри и тип на враќање. Малку е подобро, но сепак, ќе треба да напишете прилично поголем код .




3. Најдоброто решение за оваа задача е да напишете урнек на функции/ шаблон што ќе работи со сите овие типови.
Ова е можно бидејќи преклопените функции извршуваат исти операции врз различни типови податоци. Таквата функција се нарекува функциски шаблон

Дефинирање на шаблон за функција

template < lista na parametri>

листата на параметри содржи тип на параметрот, пред кој се наведува резервираниот збор typename

template <typename T>
template <typename T1, typename T2>

template <typename  T>

T functionName (T  parameter1, T  parameter2, ...)

{

    // code

}


Во горниот код, T е шаблон параметар кој прифаќа различни типови на податоци (int, float, итн.), а typename е клучен збор.
Типот на параметрите и на повратната вредност е ист – Т.  При извршување на програмата, резултатот е ист како и решението со преоптоварени функции.

Дефиницијата на функциски шаблон е слична со дефиницијата на било која функција со параметри, со тоа што е проширена со параметри на типови податоци наречени параметри на шаблонот или формални параметри на тип.
 
При повикот на функцискиот шаблон, се врши замена на параметрите на шаблонот со соодветните аргументи на повикот, а истовремено се врши и замена на типот на параметрите со соодветниот тип на аргументите. Притоа се генерира посебна функција со изворен код и со соодветниот тип од повикот кој се нарекува специјализација на функциски шаблон.

Функциски шаблон за претходниот пример е  следниов:

      

















Програма за определување збир на два цели и два децимални броеви

  1.       Со посебни функции

#include <iostream>
using namespace std;

int plusFuncInt(int x, int y) {
return x + y;}
double plusFuncDouble(double x, double y) {
return x + y;
}

 int main() {
int myNum1 = plusFuncInt(8, 5);
double myNum2 = plusFuncDouble(4.3, 6.26);
cout << "Int: " << myNum1 << "\n";
cout << "Double: " << myNum2;
return 0;
}

 2.       Со оverloaded функции

#include <iostream>
using namespace std;

int plusFunc (int x, int y) {
return x + y;}

double plusFunc (double x, double y) {
return x + y;}

int main() {
int myNum1 = plusFunc (8, 5);
double myNum2 = plusFunc (4.3, 6.26);
cout << "Int: " << myNum1 << "\n";
cout << "Double: " << myNum2;
return 0;
}

3.       Со Функциски шаблон

#include <iostream>
using namespace std;

template < typename T >
T plusFunc (T x, T y) {
return x + y;
}

int main() {
cout << "Int: " << plusFunc (8, 5)<< "\n";
cout << "Double: " << plusFunc (4.3, 6.26);
return 0;
}

Или за било кои броеви ( цели и децимални )


#include <iostream>
using namespace std;

template < typename T >
T plusFunc(T x, T y) {
return x + y;
}

int main() {
int a,b;
double c,d;
cout<<"Vnesete dva celi broja";
cin>>a>>b;
cout << "Int: " << plusFunc(a, b) << "\n";
cout<<"Vnesete dva decimalni broja";
cin>>c>>d;
cout << "Double: " << plusFunc(c, d);
return 0; }

Пример - поголем од 2 броја 
#include <iostream>
using namespace std;
  
template <typename T> 
T myMax(T x, T y)
{
    if (x > y) return x;
    return  y;
}
  
int main()
{
    cout << myMax   (3, 7) << endl; // Call myMax for int
    cout << myMax<double>(3.0, 7.0)  << endl; // call myMax for double
 cout << myMax<char>('g', 'e')  << endl; // call myMax for char
     return 0; }

Определи што работи следнава програма 



Определи што работи следнава програма 

class == typename ( typename se koristi za site) // изврши корекција при  run 


// function template
#include <iostream>
using namespace std;

template <class T>
T GetMax (T a, T b) {
  T result;
  if(a>b) result =a; else result =b;
  return (result);
}

int main () {
  int i=5, j=6, k;
  long l=10, m=5, n;
  k=GetMax (i,j); //k=GetMax<int>(i,j);
n=GetMax (l,m); // n=GetMax<long>(l,m);
cout << k << endl; cout << n << endl; return 0; }

Example: Adding Two Numbers Using Function Templates

#include <iostream>
using namespace std;
template <typename T>
T add(T num1, T num2) {
    return (num1 + num2);
}

int main() {
    int result1;
    double result2;
    // calling with int parameters
    result1 = add<int>(2, 3);
    cout << "2 + 3 = " << result1 << endl;
    // calling with double parameters
    result2 = add<double>(2.2, 3.3);
    cout << "2.2 + 3.3 = " << result2 << endl;
    return 0; 
}
Output:
2 + 3 = 5
2.2 + 3.3 = 5.5

Во претходниот пример извршени се неколку корекции. Објасни !
#include <iostream>
using namespace std;
template <typename T>
T add(T num1, T num2) {
    return (num1 + num2);
}

int main() {
    double result1;
    double result2;
    // 
    result1 = add <double> (2.4, 3);
    cout << "result1 = " << result1 << endl;
    // 
    result2 = add<int>(2.2, 3.3);
    cout << "result2 = " << result2 << endl;
    return 0; 
}
Output :
result1 = 5.4
result2 = 5

#include <iostream>
using namespace std;
template <typename T>
T add(T num1, T num2) {
    return (num1 + num2);
}

int main() {
    double result1;
    int result2;
    // 
    result1 = add <int> (2.4, 3.3);
    cout << "result1 = " << result1 << endl;
    // 
    result2 = add<double>(2.2, 3.3);
    cout << "result2 = " << result2 << endl;
    return 0; 
}
Output :
result1 = 5
result2 = 5


Function templates with non-template parameters

It’s possible to create function templates that have both template types and non-template type parameters. The template parameters can be matched to any type, and the non-template parameters work like the parameters of normal functions. 

# include <iostream>
using namespace std;
template <typename T>
int someFcn (T x, double y)
{
    return x+y;
}

int main()
{
    cout<<someFcn(1, 3.4)<<"   "; // matches someFcn(int, double)
    cout<<someFcn(1, 3.4f)<<"   "; // matches someFcn(int, double) -- the float is promoted to a double
    cout<<someFcn(1.2, 3.4)<<"   "; // matches someFcn(double, double)
    cout<<someFcn(1.2f, 3.4)<<"   "; // matches someFcn(float, double)
    cout<<someFcn(1.2f, 3.4f); // matches someFcn(float, double) -- the float is promoted to a double
    return 0;
}
Output:
4  4  4  4  4

Во претходниот пример извршени се неколку корекции. Објасни !
# include <iostream>
using namespace std;
template <typename T>
T someFcn (T x, double y)
{
    return x+y;
}

int main()
{
    cout<<someFcn(1, 3.4)<<"   "; // matches someFcn(int, double)
    cout<<someFcn(1, 3.4f)<<"   "; // matches someFcn(int, double) -- the float is promoted to a double
    cout<<someFcn(1.2, 3)<<"   "; // matches someFcn(double, double)
    cout<<someFcn(1.2f, 3.4)<<"   "; // matches someFcn(float, double)
    cout<<someFcn(1.2f, 3.4f); // matches someFcn(float, double) -- the float is promoted to a double
    return 0;
}
Output:
4  4  4.2  4.6  4.6


No comments: