C ++ - Vorlagen
Vorlagen bilden die Grundlage für die generische Programmierung, bei der Code unabhängig von einem bestimmten Typ geschrieben wird.
Eine Vorlage ist eine Blaupause oder Formel zum Erstellen einer generischen Klasse oder Funktion. Die Bibliothekscontainer wie Iteratoren und Algorithmen sind Beispiele für generische Programmierung und wurden unter Verwendung des Vorlagenkonzepts entwickelt.
Für jeden Container gibt es eine einzige Definition, z vector, aber wir können zum Beispiel viele verschiedene Arten von Vektoren definieren, vector <int> oder vector <string>.
Sie können Vorlagen verwenden, um Funktionen und Klassen zu definieren. Lassen Sie uns sehen, wie sie funktionieren.
Funktionsvorlage
Die allgemeine Form einer Vorlagenfunktionsdefinition wird hier gezeigt -
template <class type> ret-type func-name(parameter list) {
// body of function
}
Hier ist type ein Platzhaltername für einen Datentyp, der von der Funktion verwendet wird. Dieser Name kann innerhalb der Funktionsdefinition verwendet werden.
Das folgende Beispiel zeigt eine Funktionsvorlage, die maximal zwei Werte zurückgibt:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b) {
return a < b ? b:a;
}
int main () {
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
Wenn wir den obigen Code kompilieren und ausführen, würde dies das folgende Ergebnis erzeugen:
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World
Klassenvorlage
So wie wir Funktionsvorlagen definieren können, können wir auch Klassenvorlagen definieren. Die allgemeine Form einer generischen Klassendeklaration wird hier gezeigt -
template <class type> class class-name {
.
.
.
}
Hier, typeist der Name des Platzhaltertyps, der angegeben wird, wenn eine Klasse instanziiert wird. Sie können mehr als einen generischen Datentyp definieren, indem Sie eine durch Kommas getrennte Liste verwenden.
Das folgende Beispiel definiert die Klasse Stack <> und implementiert generische Methoden, um die Elemente vom Stapel zu verschieben und zu entfernen.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems; // elements
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const { // return true if empty.
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem) {
// append copy of passed element
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop () {
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// remove last element
elems.pop_back();
}
template <class T>
T Stack<T>::top () const {
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// return copy of last element
return elems.back();
}
int main() {
try {
Stack<int> intStack; // stack of ints
Stack<string> stringStack; // stack of strings
// manipulate int stack
intStack.push(7);
cout << intStack.top() <<endl;
// manipulate string stack
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
} catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
Wenn wir den obigen Code kompilieren und ausführen, würde dies das folgende Ergebnis erzeugen:
7
hello
Exception: Stack<>::pop(): empty stack