Was bedeutet Vorlage ?

Wenn ich eine Vorlage deklariere, bin ich daran gewöhnt, diese Art von Code zu haben:

template  

Aber in dieser Frage verwendeten sie:

 template  

Ich überprüfte, dass es kompiliert. Aber was bedeutet es? Ist es ein Nicht-Typ-Parameter? Und wenn ja, wie können wir eine Vorlage ohne irgendeinen Typparameter haben?

Solutions Collecting From Web of "Was bedeutet Vorlage ?"

Es ist durchaus möglich, eine class auf eine Ganzzahl und nicht auf einen Typ zu legen. Wir können den Templated-Wert einer Variablen zuweisen oder sie auf andere Weise wie jedes andere Integer-Literal manipulieren:

 unsigned int x = N; 

Tatsächlich können wir Algorithmen erstellen, die zur Kompilierzeit auswerten (aus Wikipedia ):

 template  struct Factorial { enum { value = N * Factorial::value }; }; template <> struct Factorial<0> { enum { value = 1 }; }; // Factorial<4>::value == 24 // Factorial<0>::value == 1 void foo() { int x = Factorial<4>::value; // == 24 int y = Factorial<0>::value; // == 1 } 

Ja, es ist ein Nicht-Typ-Parameter. Sie können verschiedene Arten von Vorlagenparametern verwenden

  • Geben Sie Parameter ein.
    • Typen
    • Vorlagen (nur classn und Aliasvorlagen, keine functionen oder Variablenvorlagen)
  • Nicht-Typ-Parameter
    • pointers
    • Verweise
    • Integrale konstante Ausdrücke

Was du dort hast, ist von letzter Art. Es ist eine Kompilierzeitkonstante (sogenannter konstanter Ausdruck) und hat den Typ Integer oder Enumeration. Nachdem ich im Standard nachgeschlagen hatte, musste ich classnvorlagen in den Typbereich verschieben – obwohl Vorlagen keine Typen sind. Sie werden jedoch Typ-Parameter genannt, um diese Arten dennoch zu beschreiben. Sie können pointers (und auch Elementzeiger) und Verweise auf Objekte / functionen haben, die eine externe Verknüpfung haben (solche, die mit anderen Objektdateien verknüpft werden können und deren Adresse im gesamten Programm eindeutig ist). Beispiele:

Templatetyp-Parameter:

 template struct Container { T t; }; // pass type "long" as argument. Container test; 

Template-Integer-Parameter:

 template struct Vector { unsigned char bytes[S]; }; // pass 3 as argument. Vector<3> test; 

Template-pointers-Parameter (Übergabe eines pointerss an eine function)

 template struct FunctionWrapper { static void call_it() { F(); } }; // pass address of function do_it as argument. void do_it() { } FunctionWrapper< &do_it> test; 

Vorlagenreferenzparameter (Übergabe einer Ganzzahl)

 template struct SillyExample { static void do_it() { A = 10; } }; // pass flag as argument int flag; SillyExample test; 

Vorlagenschablonenparameter

 template 

Eine Vorlage ohne Parameter ist nicht möglich. Aber eine Vorlage ohne explizites Argument ist möglich – sie hat Standardargumente:

 template struct Vector { unsigned char buffer[SIZE]; }; Vector<> test; 

Syntaktisch ist die template<> reserviert, um eine explizite Template-Spezialisierung anstelle einer Vorlage ohne Parameter zu markieren:

 template<> struct Vector<3> { // alternative definition for SIZE == 3 }; 

Sie templatisieren Ihre class basierend auf einem ‘unsigned int’.

Beispiel:

 template  class MyArray { public: private: double data[N]; // Use N as the size of the array }; int main() { MyArray<2> a1; MyArray<2> a2; MyArray<4> b1; a1 = a2; // OK The arrays are the same size. a1 = b1; // FAIL because the size of the array is part of the // template and thus the type, a1 and b1 are different types. // Thus this is a COMPILE time failure. } 

Eine Template-class ist wie ein Makro, nur viel weniger böse.

Stellen Sie sich eine Vorlage als Makro vor. Die Parameter für die Vorlage werden in eine classn- (oder functions) -Definition eingefügt, wenn Sie eine class (oder function) mithilfe einer Vorlage definieren.

Der Unterschied besteht darin, dass die Parameter “types” haben und die übergebenen Werte beim Übersetzen überprüft werden, wie zB Parameter zu functionen. Die gültigen Typen sind Ihre regulären C ++ – Typen, wie int und char. Wenn Sie eine Schablonenklasse instanziieren, übergeben Sie einen Wert des angegebenen Typs, und in einer neuen Kopie der Schablonenklassendefinition wird dieser Wert ersetzt, unabhängig davon, wo sich der Parametername in der ursprünglichen Definition befand. Genau wie ein Makro.

Sie können auch die Typen ” class ” oder ” typename ” für Parameter verwenden (sie sind wirklich identisch). Bei einem Parameter eines dieser Typen können Sie anstelle eines Werts einen Typnamen übergeben. Genau wie zuvor, überall wo der Parametername in der Template-classndefinition war, wird, sobald Sie eine neue Instanz erstellen, welcher Typ auch immer übergeben. Dies ist die häufigste Verwendung für eine Vorlagenklasse. Jeder, der etwas über C ++ – Vorlagen weiß, weiß, wie das geht.

Berücksichtigen Sie diesen Vorlagenklassenbeispielcode:

 #include  template  class foo { void print() { printf("%i", I); } }; int main() { foo<26> f; f.print(); return 0; } 

Es ist funktional identisch mit diesem Makro-Code:

 #include  #define MAKE_A_FOO(I) class foo_##I \ { \ void print() \ { \ printf("%i", I); \ } \ }; MAKE_A_FOO(26) int main() { foo_26 f; f.print(); return 0; } 

Natürlich ist die Template-Version eine Milliarde Mal sicherer und flexibler.