A sjabloon is een eenvoudige maar zeer krachtige tool in C++. Het simpele idee is om het gegevenstype als parameter door te geven, zodat we niet dezelfde code voor verschillende gegevenstypen hoeven te schrijven. Een softwarebedrijf moet bijvoorbeeld mogelijk sorteren() voor verschillende gegevenstypen. In plaats van meerdere codes te schrijven en te onderhouden, kunnen we één sort() schrijven en het datatype als parameter doorgeven.
C++ voegt twee nieuwe trefwoorden toe ter ondersteuning van sjablonen: 'sjabloon' En ‘typenaam’ . Het tweede trefwoord kan altijd worden vervangen door het trefwoord 'klas' .
Hoe werken sjablonen?
Sjablonen worden tijdens het compileren uitgebreid. Dit lijkt op macro's. Het verschil is dat de compiler typecontrole uitvoert voordat de sjabloon wordt uitgebreid. Het idee is simpel: de broncode bevat alleen een functie/klasse, maar gecompileerde code kan meerdere kopieën van dezelfde functie/klasse bevatten.
Functiesjablonen
We schrijven een generieke functie die voor verschillende gegevenstypen kan worden gebruikt. Voorbeelden van functiesjablonen zijn sort(), max(), min(), printArray().
Voor meer informatie over het onderwerp verwijzen wij u naar Generieken in C++ .
Voorbeeld:
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 '>' is een overbelast sjabloonT mijnMax(T x, T y) { return (x> y) ? x: y; } int main() {// Roep myMax aan voor 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; }>
Uitvoer
7 7 g>
Voorbeeld: Implementeren Bellen sorteren met behulp van sjablonen in C++
interne werking van hashmapC++
// 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 (een); uit<< ' Sorted array : '; for (int i = 0; i < n; i++) cout << a[i] << ' '; cout << endl; return 0; }>
Uitvoer
Sorted array : 10 20 30 40 50>
Klassensjablonen
Klassensjablonen zoals functiesjablonen en klassensjablonen zijn handig wanneer een klasse iets definieert dat onafhankelijk is van het gegevenstype. Kan handig zijn voor klassen zoals LinkedList, BinaryTree, Stack, Queue, Array, enz.
Voorbeeld:
C++ // C++ Program to implement // template Array class #include using namespace std; template klasse Array { privé: T* ptr; int-grootte; publiek: Array(T arr[], int s); ongeldige print(); }; sjabloonArray::Array(T arr[], int s) { ptr = nieuwe T[s]; maat = s; voor (int i = 0; ik< size; i++) ptr[i] = arr[i]; } template ongeldige array::print() { for (int i = 0; ik< size; i++) cout << ' ' << *(ptr + i); cout << endl; } int main() { int arr[5] = { 1, 2, 3, 4, 5 }; Array a(arr, 5); een print(); retour 0; }>
Uitvoer
1 2 3 4 5>
Kan er meer dan één argument zijn voor sjablonen?
Ja, net als bij normale parameters kunnen we meer dan één gegevenstype als argumenten aan sjablonen doorgeven. Het volgende voorbeeld laat hetzelfde zien.
Voorbeeld:
C++ // C++ Program to implement // Use of template #include using namespace std; template klasse A { T x; U y; openbaar: A() {cout<< 'Constructor Called' << endl; } }; int main() { AA; A B; retour 0; }>
Uitvoer
Constructor Called Constructor Called>
Kunnen we een standaardwaarde voor sjabloonargumenten opgeven?
Ja, net als bij normale parameters kunnen we standaardargumenten voor sjablonen opgeven. Het volgende voorbeeld laat hetzelfde zien.
Voorbeeld:
C++ // C++ Program to implement // Use of template #include using namespace std; template klasse A { publiek: T x; U y; A() { uit<< 'Constructor Called' << endl; } }; int main() { // This will call A AA; retour 0; }>
Uitvoer
Constructor Called>
Wat is het verschil tussen functieoverbelasting en sjablonen?
Zowel functieoverbelasting als sjablonen zijn voorbeelden van polymorfistische kenmerken van OOP. Overbelasting van functies wordt gebruikt wanneer meerdere functies vrijwel dezelfde (niet identieke) bewerkingen uitvoeren, sjablonen worden gebruikt wanneer meerdere functies identieke bewerkingen uitvoeren.
Wat gebeurt er als er een statisch lid in een sjabloonklasse/functie aanwezig is?
Elke instantie van een sjabloon bevat zijn eigen statische variabele. Zien Sjablonen en statische variabelen voor meer details.
Wat is sjabloonspecialisatie?
Door sjabloonspecialisatie kunnen we verschillende codes hebben voor een bepaald gegevenstype. Zien Sjabloonspecialisatie voor meer details.
javascriptvariabele globaal
Kunnen we niet-typeparameters doorgeven aan sjablonen?
We kunnen niet-type argumenten doorgeven aan sjablonen. Niet-type parameters worden voornamelijk gebruikt voor het opgeven van maximale of minimale waarden of een andere constante waarde voor een bepaald exemplaar van een sjabloon. Het belangrijkste om op te merken over niet-type parameters is dat ze const moeten zijn. De compiler moet tijdens het compileren de waarde kennen van niet-type parameters. Omdat de compiler tijdens het compileren functies/klassen moet maken voor een opgegeven niet-typewaarde. Als we in het onderstaande programma 10000 of 25 vervangen door een variabele, krijgen we een compilerfout.
Voorbeeld:
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; voor (int i = 0; ik< 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); retour 0; }>
Uitvoer
10 1>
Hier is een voorbeeld van een C++-programma om verschillende gegevenstypen weer te geven met behulp van een constructor en een sjabloon. We zullen een aantal acties uitvoeren
- tekenwaarde doorgeven door een object te maken in de functie main().
- het doorgeven van een geheel getal door een object te maken in de functie main().
- float-waarde doorgeven door een object te maken in de functie main().
Voorbeeld:
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: // constructor van type template info(TA) { 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'); // gehele waarde doorgeven door een objectinfo te maken q(22); // floatwaarde doorgeven door objectinfo te makenr(2,25); retour 0; }>
Uitvoer
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>
Sjabloonargumentaftrek
Met sjabloonargumentaftrek wordt automatisch het gegevenstype afgeleid van het argument dat aan de klasse- of functiesjablonen wordt doorgegeven. Hierdoor kunnen we de sjabloon instantiëren zonder het gegevenstype expliciet op te geven.
arraylist java sorteren
Bekijk bijvoorbeeld het onderstaande functiesjabloon om twee getallen te vermenigvuldigen:
template t multiply (t num1,t num2) { return num1*num2; }>Als we de functie multiply() voor gehele getallen willen gebruiken, moeten we deze over het algemeen als volgt aanroepen:
multiply (25, 5);>
Maar we kunnen het ook noemen:
multiply(23, 5);>
We specificeren het type niet expliciet, dat wil zeggen dat 1,3 gehele getallen zijn.
Hetzelfde geldt voor de sjabloonklassen (alleen sinds C++17). Stel dat we de sjabloonklasse definiëren als:
template class student{ private: t total_marks; public: student(t x) : total_marks(x) {} };>Als we een instantie van deze klasse willen maken, kunnen we een van de volgende syntaxis gebruiken:
student stu1(23); or student stu2(24);>
Opmerking: Het is belangrijk op te merken dat de sjabloonargumentaftrek voor klassen alleen beschikbaar is sinds C++17, dus als we de automatische sjabloonargumentaftrek voor een klasse in de vorige versie proberen te gebruiken, zal dit een foutmelding opleveren.
Voorbeeld van sjabloonargumentaftrek
Het onderstaande voorbeeld laat zien hoe de STL-vectorklassesjabloon het gegevenstype afleidt zonder expliciet te worden gespecificeerd.
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 << ' '; } }>
Uitvoer
Elements of v1 : 1.1 2 3.9 4.909 Elements of v2 : 1 2 3 4>
Opmerking: Het bovenstaande programma mislukt de compilatie in de compiler C++14 en lager, omdat de deductie van klassensjabloonargumenten is toegevoegd in C++17.
Functie Sjabloon Argumenten Aftrek
Functiesjabloonargumentaftrek is onderdeel van C++ sinds de C++98-standaard. We kunnen het declareren van het type argumenten dat we willen doorgeven aan de functiesjabloon overslaan en de compiler zal het type automatisch afleiden met behulp van de argumenten die we hebben doorgegeven in de functieaanroep.
chown-opdracht
Voorbeeld: In het volgende voorbeeld laten we zien hoe functies in C++ automatisch hun type afleiden.
C++ // C++ program to illustrate the function template argument // deduction #include using namespace std; // defining function template template t vermenigvuldigen(t eerst, t tweede) { return eerst * tweede; } // stuurprogrammacode int main() {auto result = multiply(10, 20); std::uit<< 'Multiplication OF 10 and 20: ' << result << std::endl; return 0; }>
Uitvoer
Multiplication OF 10 and 20: 200>
Opmerking: Voor de functiesjablonen die hetzelfde type hebben voor de argumenten zoals template void function(t a1, t a2){}, kunnen we geen argumenten van verschillende typen doorgeven.
Aftrek van klassensjabloonargumenten (vanaf C++17)
De deductie van het klassensjabloonargument is toegevoegd in C++17 en maakt sindsdien deel uit van de taal. Het stelt ons in staat om de klassensjablooninstanties te maken zonder de typen expliciet te definiëren, net als bij functiesjablonen.
boolean om Java te stringen
Voorbeeld: In het volgende voorbeeld laten we zien hoe de compiler automatisch sjablonen classificeert in C++.
C++ // C++ Program to implement Class Template Arguments // Deduction #include #include #include using namespace std; // Defining class template template klas leerling { privé: string leerling_naam; T totaal_punten; public: // Geparametriseerde constructor student(string n, T m) : student_name(n), total_marks(m) { } void getinfo() {// de details van de studentencout afdrukken<< '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; }>
Uitvoer
STUDENT NAME: Vipul TOTAL MARKS: 100 Type ID: i STUDENT NAME: Yash TOTAL MARKS: 98.5 Type ID: d>
Hier betekent i int, en d betekent dubbel.
Voor sjabloonmetaprogrammering is r zie het volgende artikel – Metaprogrammering van sjablonen .
Neem een Quiz over sjablonen . Java ondersteunt deze functies ook. Java noemt het Merkloos product .
