2016-08-04 15 views
0

Immer wenn ich eine Vorlage erstelle, weiß ich, dass sie als Funktionsargumente übergeben wird, aber gibt es einen bestimmten Grund, warum ich keine Vorlagen innerhalb meiner Hauptfunktion verwenden kann?Gibt es trotzdem Templates NICHT als Parameter, sondern als globalen Typ zu verwenden?

template <class Tmp> 

int main() 
{ 
    Tmp pizza; 

} 

Aber als Parameter übergeben wird immer

template <class Tmp> 
Tmp add(Tmp x, Tmp y) 
{ 
    return x+y; 

} 

Der obige Code meiner versucht variable Deklarationszeile es Zustand „Unbekannter Typ‚Tmp‘“ wird nicht ausgeführt, und als nächstes arbeiten, aber ich davon aus, dass wegen Ich habe die Vorlage außerhalb meiner Hauptfunktion deklariert. Gibt es einen bestimmten Grund, warum das so ist? Es scheint, als ob jeder nur Templates innerhalb von Funktionsparametern verwendet und nichts mehr.

+2

Vielleicht suchen Sie nach 'typedef'? – user694733

+5

Mit der Syntax ist das erste Snippet, wie (und wann) würden Sie erwarten, dass die Vorlage instanziiert wird? Was wäre 'Tmp'? – Quentin

+1

Was sagt 'Pizza', welcher Typ es ist? – Galik

Antwort

1

Sie sind fast da. Aber C++ ist eine statisch typisierte Sprache, so dass der Compiler die Typ für pizza bei kompilieren muss. Diese

template <class Y> struct/*members are public by default*/ Tmp 
{ 
    typedef Y type; 
}; 

int main() 
{ 
    Tmp<int>::type pizza; /*pizza will be an int*/ 
} 

ist legal.

1

Vorlagen sind kein Code. Vorlagen sind ... naja, sie sind Vorlagen. Bevor Sie eine Template-Funktion aufrufen können, muss sie instanziiert werden. Z.B. Diese

template <class T> T foo(T x) { return T;} 

ist nur eine Vorlage, dh wenn Sie dies allein der Compiler schreiben, wird nicht eine einzige Zeile Code für diese erstellen. Nur wenn Sie es instanziieren und verwenden der Compiler etwas tun:

int main() { 
    int x = 0; 
    int y = foo<int>(x); // compiler instantiates the template and calls the int instance 
} 

In Ihrem ersten Schnipsel der Compiler nicht weiß, welche Art sollte es verwenden, um die Vorlage zu instanziieren. Außerdem können Sie main keine Vorlage erstellen, da der Einstiegspunkt eines beliebigen Programms int main() sein muss.

PS:

Es scheint, als ob jeder nur Vorlagen innerhalb von Funktionsparametern verwendet und nichts mehr.

Es gibt mehr Dinge, die man mit Vorlagen tun kann. Ich denke über Vorlagen wie die Art nach, um meinen Code zu parametrisieren, wann immer der Parameter zur Kompilierungszeit gewählt werden kann. Betrachten Sie diese (ein wenig gekünstelt) Beispiel:

// template taking a functor as argument 
// (more precisely: a default constructible callable type) 
template <typename op,typename T> void plug(T x) { 
    std::cout << "op(" << x << ") = " << op()(x) << "\n"; 
} 

// a simple functor 
template <typename T> 
struct identity { T operator()(T x){return x;} }; 

int main() { 
    plug<identity<double>,double>(2.0); 
} 
// prints: 
// op(2) = 2 

Sobald instanziiert, der Parameter erscheint nicht als Funktionsparameter, sondern es vielmehr kontrolliert, was die (Templat) Funktion tatsächlich mit seinem Parameter tut.

+0

"Vorlagen sind kein Code. Vorlagen sind ... nun, sie sind Vorlagen". Gut gemacht, plus eins. – Bathsheba

1

ist es ein besonderer Grund, warum ich Templates nicht in meiner Hauptfunktion

Es gibt keinen Grund, warum Sie kannst nicht, aber Ihr Code nicht verwendet Vorlagen in Ihrer Hauptfunktion nutzen kann. Stattdessen versucht Ihr Code, main als Funktionsvorlage zu definieren.Das ist nicht gut, weil die Signatur main im Standard angegeben ist und es keine Funktionsvorlage ist. Zugegeben, Implementierungen dürfen Alternativen angeben, aber das hilft Ihnen nicht, da Ihre Implementierung keine Vorlagenfunktionsalternativen angibt. Mein Compiler (gcc) verursacht eine mutigere Fehlermeldung als deine, es sagt:

error: cannot declare ‘::main’ to be a template 

Sie schreiben, als ob Sie glauben, dass Tmp eine Vorlage genannt wird. Wenn ja, korrigieren Sie das, indem Sie auf Ihr Lehrbuch/Tutorial/was auch immer zurückblicken. Tmpist keine Vorlage. Es ist ein Vorlagenparameter. In Ihrem zweiten Code-Snippet ist add eine Funktionsvorlage, und Tmp ist immer noch keine Vorlage, es ist der Vorlagenparameter von add.

Sie können Vorlagenparameter innerhalb der Vorlage verwenden, deren Parameter sie sind. Zum Beispiel ist die folgende fein:

template <class Tmp> 
Tmp add(Tmp x, Tmp y) 
{ 
    Tmp total = x + y; 
    return total; 
} 

Ihr Problem ist nur, dass, wenn Sie dies versuchen, es in main versucht, was nicht eine Vorlage sein kann.