2009-04-28 4 views
27

Manchmal funktioniert es manchmal nicht:Wenn ein Compiler auf einen Template-Parameter schließen kann?

template <class T> 
void f(T t) {} 

template <class T> 
class MyClass { 
public: 
    MyClass(T t) {} 
}; 

void test() { 
    f<int>(5); 
    MyClass<int> mc(5); 
    f(5); 
    MyClass mc(5); // this doesn't work 
} 

Gibt es eine Möglichkeit oben um das Beispiel zu hacken? I.e. Erzwinge dem Compiler, den Template-Parameter aus dem Konstruktorparameter abzuleiten.

Wird dies in der Zukunft behoben werden, oder gibt es einen guten Grund nicht zu?

Was ist die allgemeine Regel, wenn der Compiler Template-Parameter ableiten kann?

Antwort

47

Template-Parameter können

es kann also geschlossen werden hier geschlossen für werden können Parameter aus der Vorlage Funktionsschablonen wenn der Parametertyp abgeleitet werden:

template <typename T> 
void f(T t); 

template <typename T> 
void f(std::vector<T> v); 

aber nicht hier:

template <typename T> 
T f() { 
    return T(); 
} 

Und nicht in Klassenvorlagen.

Also die übliche Lösung für Ihr Problem ist es, eine Wrapper-Funktion, ähnlich wie die Standardbibliothek Funktion std::make_pair zu erstellen:

template <class T> 
    class MyClass { 
    public: 
     MyClass(T t) {} 
     void print(){ 
      std::cout<<"try MyClass"<<std::endl; 
     } 
    }; 

    template <typename T> 
    MyClass<T> MakeMyClass(T t) { return MyClass<T>(t); } 

und dann auto a = MakeMyClass(5); die Klasse zu instanziiert nennen.

+0

+1, gründlich. Minor nit: Ich empfehle, "wenn der Parametertyp abhängig ist" zu "wenn ein Parametertyp abhängig ist" zu ändern. –

+2

void f (Typname T :: const_iterator t); << hier erscheint T in einem nicht reduzierbaren Kontext. selbst wenn es mit einem Vektor :: const_iterator aufgerufen wird, zum Beispiel wird es nicht in der Lage sein, den Vektor für T. abzuleiten. Der Grund ist, dass die Bedeutung von :: const_iterator von T. abhängt, aber T wiederum von der Bedeutung von abhängt :: const_iterator Deshalb ist boost :: implicit_cast wie folgt codiert: template T implicy_cast (typenname identity :: typ t) {return t; } Auch hier haben wir einen nicht erklärbaren Kontext. –

+0

Standard-Ref ist 14.8.2.4/4 (letzter C++ 1x Entwurf hat es bei 14.9.2.5/5 - behebt auch einige der Mängel der Formulierung in der aktuellen Norm). :) Prost –

Verwandte Themen