logo

Šablonai C++ su pavyzdžiais

A šabloną yra paprastas, bet labai galingas C++ įrankis. Paprasta idėja yra perduoti duomenų tipą kaip parametrą, kad mums nereikėtų rašyti to paties kodo skirtingiems duomenų tipams. Pavyzdžiui, programinės įrangos įmonei gali tekti rūšiuoti () pagal skirtingus duomenų tipus. Užuot rašę ir prižiūrėję kelis kodus, galime parašyti vieną sort () ir perduoti duomenų tipą kaip parametrą.

C++ prideda du naujus raktinius žodžius, kad palaikytų šablonus: 'šablonas' ir 'tipo pavadinimas' . Antrąjį raktinį žodį visada galima pakeisti raktiniu žodžiu 'klasė' .



Kaip veikia šablonai?

Šablonai išplečiami kompiliatoriaus metu. Tai kaip makrokomandos. Skirtumas yra tas, kad kompiliatorius patikrina tipą prieš išplėsdamas šabloną. Idėja paprasta, šaltinio kode yra tik funkcija / klasė, tačiau sudarytame kode gali būti kelios tos pačios funkcijos / klasės kopijos.

np.clip

šablonai-cpp

Funkcijų šablonai

Rašome bendrąją funkciją, kuri gali būti naudojama skirtingiems duomenų tipams. Funkcijų šablonų pavyzdžiai yra sort(), max(), min(), printArray().

Norėdami sužinoti daugiau apie temą, žr Bendra C++ kalba .



Pavyzdys:

C++
// C++ Program to demonstrate // Use of template #include  using namespace std; // One function works for all data types. This would work // even for user defined types if operator '>' yra perkrautas šablonasT myMax(T x, T y) { return (x> y) ? x : y; } int main() { // Iškvieskite myMax, kad gautumėte int cout<< myMax (3, 7)<< endl;  // call myMax for double  cout << myMax(3.0, 7.0)<< endl;  // call myMax for char  cout << myMax('g', 'e')<< endl;  return 0; }>

Išvestis
7 7 g>

Pavyzdys: Įgyvendinimas Burbulų rūšiavimas naudojant C++ šablonus

C++
// C++ Program to implement // Bubble sort // using template function #include  using namespace std; // A template function to implement bubble sort. // We can use this for any data type that supports // comparison operator  template void bubbleSort(T a[], int n) { for (int i = 0; i< n - 1; i++)  for (int j = n - 1; i < j; j--)  if (a[j] < a[j - 1])  swap(a[j], a[j - 1]); } // Driver Code int main() {  int a[5] = { 10, 50, 30, 40, 20 };  int n = sizeof(a) / sizeof(a[0]);  // calls template function  bubbleSort (a, n);  cout<< ' Sorted array : ';  for (int i = 0; i < n; i++)  cout << a[i] << ' ';  cout << endl;  return 0; }>

Išvestis
 Sorted array : 10 20 30 40 50>

Klasių šablonai

Klasių šablonai, tokie kaip funkcijų šablonai, klasių šablonai yra naudingi, kai klasė apibrėžia kažką, kas nepriklauso nuo duomenų tipo. Gali būti naudinga tokioms klasėms kaip LinkedList, BinaryTree, Stack, Queue, Array ir kt.



Pavyzdys:

C++
// C++ Program to implement // template Array class #include  using namespace std; template class Masyvas { privatus: T* ptr;  int dydis; public: Masyvas(T arr[], int s);  galiojantis spausdinimas (); }; šablonąMasyvas::Masyvas(T arr[], int s) { ptr = new T[s];  dydis = s;  už (int i = 0; i< size; i++)  ptr[i] = arr[i]; } template tuščias masyvas::print() { for (int i = 0; i< size; i++)  cout << ' ' << *(ptr + i);  cout << endl; } int main() {  int arr[5] = { 1, 2, 3, 4, 5 };  Array a(arr, 5);  a.print();  grąžinti 0; }>

Išvestis
 1 2 3 4 5>

Ar gali būti daugiau nei vienas šablonų argumentas?

Taip, kaip ir įprasti parametrai, šablonams kaip argumentus galime perduoti daugiau nei vieną duomenų tipą. Toliau pateiktas pavyzdys rodo tą patį.

Pavyzdys:

C++
// C++ Program to implement // Use of template #include  using namespace std; template klasė A { T x;  U y; viešas: A() { cout<< 'Constructor Called' << endl; } }; int main() {  Aa;  A b;  grąžinti 0; }>

Išvestis
Constructor Called Constructor Called>

Ar galime nurodyti numatytąją šablono argumentų reikšmę?

Taip, kaip ir įprasti parametrai, šablonams galime nurodyti numatytuosius argumentus. Toliau pateiktas pavyzdys rodo tą patį.

Pavyzdys:

C++
// C++ Program to implement // Use of template #include  using namespace std; template klasė A { viešas: T x;  U y;  A() { cout<< 'Constructor Called' << endl; } }; int main() {  // This will call A  Aa;  grąžinti 0; }>

Išvestis
Constructor Called>

Kuo skiriasi funkcijų perkrovimas ir šablonai?

Tiek funkcijų perkrovimas, tiek šablonai yra OOP polimorfizmo ypatybių pavyzdžiai. Funkcijų perkrovimas naudojamas, kai kelios funkcijos atlieka gana panašias (ne identiškas) operacijas, šablonai naudojami, kai kelios funkcijos atlieka identiškas operacijas.

Kas nutinka, kai šablono klasėje/funkcijoje yra statinis narys?

Kiekvienas šablono egzempliorius turi savo statinį kintamąjį. Matyti Šablonai ir statiniai kintamieji daugiau detalių.

Kas yra šablono specializacija?

Šablonų specializacija leidžia turėti skirtingus kodus tam tikram duomenų tipui. Matyti Šablonų specializacija daugiau detalių.

skirtumas tarp įmonės ir įmonės

Ar galime šablonams perduoti ne tipo parametrus?

Ne tipo argumentus galime perduoti šablonams. Netipo parametrai dažniausiai naudojami norint nurodyti maksimalias arba minimalias vertes arba bet kokią kitą pastovią konkretaus šablono egzemplioriaus reikšmę. Svarbu atkreipti dėmesį į ne tipo parametrus, kad jie turi būti konst. Kompiliatorius turi žinoti ne tipo parametrų reikšmę kompiliavimo metu. Kadangi kompiliatorius turi sukurti funkcijas/klases nurodytai ne tipo reikšmei kompiliavimo metu. Žemiau esančioje programoje, jei 10000 arba 25 pakeisime kintamuoju, gausime kompiliatoriaus klaidą.

konverteris iš eilutės į int

Pavyzdys:

C++
// C++ program to demonstrate // working of non-type parameters // to templates in C++ #include  using namespace std; template int arrMin(T arr[], int n) { int m = max;  už (int i = 0; i< n; i++)  if (arr[i] < m)  m = arr[i];  return m; } int main() {  int arr1[] = { 10, 20, 15, 12 };  int n1 = sizeof(arr1) / sizeof(arr1[0]);  char arr2[] = { 1, 2, 3 };  int n2 = sizeof(arr2) / sizeof(arr2[0]);  // Second template parameter  // to arrMin must be a  // constant  cout << arrMin (arr1, n1)<< endl;  cout << arrMin(arr2, n2);    grąžinti 0; }>

Išvestis
10 1>

Čia yra C++ programos, skirtos rodyti skirtingus duomenų tipus naudojant konstruktorių ir šabloną, pavyzdys. Atliksime keletą veiksmų

  • simbolio reikšmės perdavimas sukuriant objektą funkcijoje main().
  • sveikojo skaičiaus vertės perdavimas sukuriant objektą funkcijoje main().
  • slankiosios reikšmės perdavimas sukuriant objektą funkcijoje main().

Pavyzdys:

C++
// C++ program to show different data types using a // constructor and template. #include  using namespace std; // defining a class template template class info { public: // konstruktorius tipo šablonas info(T A) { cout<< '
'  << 'A = ' << A  << ' size of data in bytes:' << sizeof(A);  }  // end of info() }; // end of class // Main Function int main() {  // clrscr();  // passing character value by creating an objects  infop('x');  // sveikojo skaičiaus vertės perdavimas sukuriant objekto informaciją q(22);  // plūduriuojančios vertės perdavimas sukuriant objekto informacijąr(2,25);  grąžinti 0; }>

Išvestis
A = x size of data in bytes:1 A = 22 size of data in bytes:4 A = 2.25 size of data in bytes:4>

Šablono argumentų išskaičiavimas

Šablono argumentų išskaičiavimas automatiškai nustato argumento duomenų tipą, perduodamą klasės arba funkcijos šablonams. Tai leidžia mums sukurti šabloną aiškiai nenurodant duomenų tipo.

Pavyzdžiui, apsvarstykite toliau pateiktą funkcijos šabloną, kad padaugintumėte du skaičius:

template  t multiply (t num1,t num2) { return num1*num2; }>

Apskritai, kai norime naudoti funkciją multiply() sveikiesiems skaičiams, turime ją vadinti taip:

multiply (25, 5);>

Bet mes taip pat galime vadinti:

multiply(23, 5);>

Mes aiškiai nenurodome tipo, ty 1,3 yra sveikieji skaičiai.

Tas pats pasakytina ir apie šablonų klases (tik nuo C++17). Tarkime, kad šablono klasę apibrėžiame taip:

template class student{  private:  t total_marks;  public:  student(t x) : total_marks(x) {} };>

Jei norime sukurti šios klasės egzempliorių, galime naudoti bet kurią iš šių sintaksės:

student stu1(23);    or  student stu2(24);>

Pastaba: Svarbu pažymėti, kad šablono argumentų išskaičiavimas klasėms yra prieinamas tik nuo C++17, taigi, jei bandysime naudoti automatinį šablono argumentų išskaičiavimą klasei ankstesnėje versijoje, bus rodoma klaida.

Šablono argumento išskaičiavimo pavyzdys

Toliau pateiktame pavyzdyje parodyta, kaip STL vektoriaus klasės šablonas išveda duomenų tipą, aiškiai nenurodant.

C++
// C++ Program to illustrate template arguments deduction in // STL #include  #include  using namespace std; int main() {  // creating a vector object without specifying  // type  vector v1{ 1.1, 2.0, 3.9, 4.909 };  cout << 'Elements of v1 : ';  for (auto i : v1) {  cout << i << ' ';  }  // creating a vector object without specifying type  vector v2{ 1, 2, 3, 4 };  cout << endl << 'Elements of v2 : ';  for (auto i : v2) {  cout << i << ' ';  } }>


Išvestis

Elements of v1 : 1.1 2 3.9 4.909  Elements of v2 : 1 2 3 4>

Pastaba: Pirmiau nurodytos programos kompiliavimas nepavyks C++14 ir žemesniuose kompiliatoriuose, nes C++17 buvo pridėtas klasės šablono argumentų išskaičiavimas.

Funkcijų šablono argumentai Išskaičiavimas

Funkcijų šablono argumentų išskaičiavimas buvo C++ dalis nuo pat C++98 standarto. Galime praleisti argumentų, kuriuos norime perduoti, tipo deklaravimą funkcijos šablonui, o kompiliatorius automatiškai nustatys tipą naudodamas argumentus, kuriuos perdavėme funkcijos iškvietime.

diskretiškasis matematikos neigimas

Pavyzdys: Šiame pavyzdyje parodome, kaip C++ funkcijos automatiškai nustato savo tipą pačios.

žodžių įvyniojimas css
C++
// C++ program to illustrate the function template argument // deduction #include  using namespace std; // defining function template template t dauginti(t pirma, t antra) { return pirmas * antras; } // vairuotojo kodas int main() { automatinis rezultatas = multiply(10, 20);  std::cout<< 'Multiplication OF 10 and 20: ' << result  << std::endl;  return 0; }>

Išvestis
Multiplication OF 10 and 20: 200>

Pastaba: Funkcijų šablonams, kurių argumentai yra vienodi, pvz., šablono void function(t a1, t a2){}, negalime perduoti skirtingų tipų argumentų.

Klasės šablono argumentų išskaičiavimas (C++17 ir toliau)

Klasės šablono argumentų išskaičiavimas buvo įtrauktas į C++17 ir nuo to laiko yra kalbos dalis. Tai leidžia mums sukurti klasės šablonų egzempliorius aiškiai neapibrėžiant tipų, kaip ir funkcijų šablonus.

Pavyzdys: Šiame pavyzdyje parodome, kaip kompiliatorius automatiškai klasifikuoja šablonus C++.

C++
// C++ Program to implement Class Template Arguments // Deduction #include  #include  #include  using namespace std; // Defining class template template klasės mokinys { privatus: string studento_vardas;  T total_marks; public: // Parametrizuotas konstruktorius student(string n, T m) : studento_vardas(n) , total_marks(m) { } void getinfo() { // studento cout detalių spausdinimas<< 'STUDENT NAME: ' << student_name << endl;  cout << 'TOTAL MARKS: ' << total_marks << endl;  cout << 'Type ID: ' << typeid(total_marks).name()  << endl;  } }; int main() {  student s1('Vipul', 100); // Deduces student  student s2('Yash', 98.5); // Deduces student  s1.getinfo();  s2.getinfo();  return 0; }>


Išvestis

STUDENT NAME: Vipul TOTAL MARKS: 100 Type ID: i STUDENT NAME: Yash TOTAL MARKS: 98.5 Type ID: d>

Čia i reiškia int, o d reiškia dvigubą.

Šablonų metaprogramavimui r skaitykite šį straipsnį – Šablonų metaprogramavimas .

Paimkite a Viktorina apie šablonus . Java taip pat palaiko šias funkcijas. Java tai vadina generiniai vaistai .