logo

Vorlagen in C++ mit Beispielen

A Vorlage ist ein einfaches, aber sehr leistungsstarkes Tool in C++. Die einfache Idee besteht darin, den Datentyp als Parameter zu übergeben, sodass wir nicht denselben Code für verschiedene Datentypen schreiben müssen. Beispielsweise muss ein Softwareunternehmen möglicherweise sort() für verschiedene Datentypen verwenden. Anstatt mehrere Codes zu schreiben und zu verwalten, können wir eine sort() schreiben und den Datentyp als Parameter übergeben.

C++ fügt zwei neue Schlüsselwörter zur Unterstützung von Vorlagen hinzu: 'Vorlage' Und 'Modellname' . Das zweite Schlüsselwort kann jederzeit durch das Schlüsselwort ersetzt werden 'Klasse' .



Wie funktionieren Vorlagen?

Vorlagen werden zur Compilerzeit erweitert. Das ist wie bei Makros. Der Unterschied besteht darin, dass der Compiler vor der Vorlagenerweiterung eine Typprüfung durchführt. Die Idee ist einfach: Der Quellcode enthält nur Funktionen/Klassen, kompilierter Code kann jedoch mehrere Kopien derselben Funktion/Klasse enthalten.

templates-cpp

Funktionsvorlagen

Wir schreiben eine generische Funktion, die für verschiedene Datentypen verwendet werden kann. Beispiele für Funktionsvorlagen sind sort(), max(), min(), printArray().

Weitere Informationen zum Thema finden Sie unter Generika in C++ .



Beispiel:

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 '>' ist eine überladene VorlageT myMax(T x, T y) { return (x> y) ? x : y; } int main() { // Rufen Sie myMax für int cout auf<< 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; }>

Ausgabe
7 7 g>

Beispiel: Umsetzen Blasensortierung Verwendung von Vorlagen in C++

Inline-Stil reagieren
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 (ein);  cout<< ' Sorted array : ';  for (int i = 0; i < n; i++)  cout << a[i] << ' ';  cout << endl;  return 0; }>

Ausgabe
 Sorted array : 10 20 30 40 50>

Klassenvorlagen

Klassenvorlagen wie Funktionsvorlagen und Klassenvorlagen sind nützlich, wenn eine Klasse etwas definiert, das vom Datentyp unabhängig ist. Kann für Klassen wie LinkedList, BinaryTree, Stack, Queue, Array usw. nützlich sein.



Beispiel:

C++
// C++ Program to implement // template Array class #include  using namespace std; template class Array { private: T* ptr;  int-Größe; public: Array(T arr[], int s);  void print(); }; VorlageArray::Array(T arr[], int s) { ptr = new T[s];  Größe = s;  für (int i = 0; i< size; i++)  ptr[i] = arr[i]; } template Leeres Array::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);  Ein Druck();  0 zurückgeben; }>

Ausgabe
 1 2 3 4 5>

Kann es mehr als ein Argument für Vorlagen geben?

Ja, wie bei normalen Parametern können wir mehr als einen Datentyp als Argumente an Vorlagen übergeben. Das folgende Beispiel zeigt dasselbe.

Beispiel:

C++
// C++ Program to implement // Use of template #include  using namespace std; template Klasse A { T x;  U y; public: A() { cout<< 'Constructor Called' << endl; } }; int main() {  AA;  A B;  0 zurückgeben; }>

Ausgabe
Constructor Called Constructor Called>

Können wir einen Standardwert für Vorlagenargumente angeben?

Ja, wie bei normalen Parametern können wir Standardargumente für Vorlagen angeben. Das folgende Beispiel zeigt dasselbe.

Beispiel:

C++
// C++ Program to implement // Use of template #include  using namespace std; template Klasse A { public: T x;  U y;  A() { cout<< 'Constructor Called' << endl; } }; int main() {  // This will call A  AA;  0 zurückgeben; }>

Ausgabe
Constructor Called>

Was ist der Unterschied zwischen Funktionsüberladung und Vorlagen?

Sowohl Funktionsüberladung als auch Vorlagen sind Beispiele für Polymorphismusmerkmale von OOP. Funktionsüberladung wird verwendet, wenn mehrere Funktionen recht ähnliche (nicht identische) Vorgänge ausführen. Vorlagen werden verwendet, wenn mehrere Funktionen identische Vorgänge ausführen.

Was passiert, wenn in einer Vorlagenklasse/-funktion ein statisches Mitglied vorhanden ist?

Jede Instanz einer Vorlage enthält eine eigene statische Variable. Sehen Vorlagen und statische Variablen für mehr Details.

Was ist Vorlagenspezialisierung?

Durch die Vorlagenspezialisierung können wir unterschiedliche Codes für einen bestimmten Datentyp verwenden. Sehen Spezialisierung auf Vorlagen für mehr Details.

Können wir Nicht-Typ-Parameter an Vorlagen übergeben?

Wir können Nicht-Typ-Argumente an Vorlagen übergeben. Nicht-Typ-Parameter werden hauptsächlich zum Angeben von Maximal- oder Minimalwerten oder anderen konstanten Werten für eine bestimmte Instanz einer Vorlage verwendet. Bei Nicht-Typ-Parametern ist es wichtig zu beachten, dass sie konstant sein müssen. Der Compiler muss den Wert von Nicht-Typ-Parametern zur Kompilierungszeit kennen. Weil der Compiler zur Kompilierungszeit Funktionen/Klassen für einen angegebenen Nicht-Typ-Wert erstellen muss. Wenn wir im folgenden Programm 10000 oder 25 durch eine Variable ersetzen, erhalten wir einen Compilerfehler.

Beispiel:

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;  für (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);    0 zurückgeben; }>

Ausgabe
10 1>

Hier ist ein Beispiel für ein C++-Programm zur Darstellung verschiedener Datentypen mithilfe eines Konstruktors und einer Vorlage. Wir werden einige Aktionen durchführen

  • Übergeben eines Zeichenwerts durch Erstellen eines Objekts in der Funktion main().
  • Übergeben eines ganzzahligen Werts durch Erstellen eines Objekts in der Funktion main().
  • Übergeben eines Float-Werts durch Erstellen eines Objekts in der Funktion main().

Beispiel:

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: // Konstruktor des Typs template 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');  // Übergeben eines ganzzahligen Werts durch Erstellen einer Objektinformation q(22);  // Übergeben eines Gleitkommawerts durch Erstellen einer Objektinformationr(2,25);  0 zurückgeben; }>

Ausgabe
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>

Abzug von Vorlagenargumenten

Der Abzug von Vorlagenargumenten leitet automatisch den Datentyp des Arguments ab, das an die Klassen- oder Funktionsvorlagen übergeben wird. Dadurch können wir die Vorlage instanziieren, ohne den Datentyp explizit anzugeben.

Betrachten Sie beispielsweise die folgende Funktionsvorlage zum Multiplizieren zweier Zahlen:

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

Wenn wir die Funktion multiply() für ganze Zahlen verwenden möchten, müssen wir sie im Allgemeinen wie folgt aufrufen:

multiply (25, 5);>

Wir können es aber auch nennen:

Zeile Autocad-Befehl
multiply(23, 5);>

Wir geben den Typ nicht explizit an, d. h. 1,3 sind Ganzzahlen.

Das Gleiche gilt für die Template-Klassen (nur seit C++17). Angenommen, wir definieren die Vorlagenklasse als:

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

Wenn wir eine Instanz dieser Klasse erstellen möchten, können wir eine der folgenden Syntaxen verwenden:

Java-PGM
student stu1(23);    or  student stu2(24);>

Notiz: Es ist wichtig zu beachten, dass der Vorlagenargumentabzug für Klassen erst seit C++17 verfügbar ist. Wenn wir also versuchen, den automatischen Vorlagenargumentabzug für eine Klasse in einer früheren Version zu verwenden, wird ein Fehler ausgegeben.

Beispiel für die Ableitung von Vorlagenargumenten

Das folgende Beispiel zeigt, wie die STL-Vektorklassenvorlage den Datentyp ableitet, ohne ihn explizit anzugeben.

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 << ' ';  } }>


Ausgabe

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

Notiz: Das obige Programm schlägt bei der Kompilierung in C++14 und niedrigeren Compilern fehl, da in C++17 der Abzug von Klassenvorlagenargumenten hinzugefügt wurde.

Ableitung der Funktionsvorlagenargumente

Die Ableitung von Funktionsvorlagenargumenten ist seit dem C++98-Standard Teil von C++. Wir können die Deklaration des Typs der Argumente, die wir an die Funktionsvorlage übergeben möchten, überspringen und der Compiler leitet den Typ automatisch anhand der Argumente ab, die wir im Funktionsaufruf übergeben haben.

Beispiel: Im folgenden Beispiel demonstrieren wir, wie Funktionen in C++ ihren Typ automatisch selbst ableiten.

C++
// C++ program to illustrate the function template argument // deduction #include  using namespace std; // defining function template template t multiply(t first, t second) { return first * second; } // Treibercode int main() { auto result = multiply(10, 20);  std::cout<< 'Multiplication OF 10 and 20: ' << result  << std::endl;  return 0; }>

Ausgabe
Multiplication OF 10 and 20: 200>

Notiz: Für die Funktionsvorlagen, die denselben Typ für die Argumente haben, wie z. B. die Vorlage void function(t a1, t a2){}, können wir keine Argumente unterschiedlichen Typs übergeben.

Ableitung von Klassenvorlagenargumenten (ab C++17)

Der Klassenvorlagenargumentabzug wurde in C++17 hinzugefügt und ist seitdem Teil der Sprache. Es ermöglicht uns, Klassenvorlageninstanzen zu erstellen, ohne die Typen explizit zu definieren, genau wie Funktionsvorlagen.

Beispiel: Im folgenden Beispiel demonstrieren wir, wie der Compiler Vorlagen in C++ automatisch klassifiziert.

C++
// C++ Program to implement Class Template Arguments // Deduction #include  #include  #include  using namespace std; // Defining class template template Klasse Student { private: string student_name;  T total_marks; public: // Parametrisierter Konstruktor student(string n, T m): student_name(n) , total_marks(m) { } void getinfo() { // Druckt die Details des Studenten-Couts<< '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; }>


Ausgabe

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

Hier bedeutet i int und d bedeutet double.

Für Template-Metaprogrammierung, r Weitere Informationen finden Sie im folgenden Artikel: Vorlagen-Metaprogrammierung .

Nimm ein Quiz zu Vorlagen . Auch Java unterstützt diese Funktionen. Java nennt es Generika .