2010-11-21 15 views
1

Ich habe versucht, eine Vorlagenklasse (Test2) zu erstellen, die 2 Vorlagenargumente benötigt, Type1 und Type2. Es ist bekannt, dass das zweite Argument auch eine Vorlagenklasse wäre, die 2 Vorlagenargumente (TypeA und TypeB) benötigt.Absurde Fehler bei der Verwendung von Vorlagenvorlagenargumenten

Nun, für ein Objekt von Test2 konstruieren, mag ich den Benutzer in der Lage sein, entweder von zwei Arten von Konstrukteuren zu verwenden:

  1. Eine, die Objekte von Type1 und Type2 nimmt.
  2. Eine, die Objekte von Type1, TypeA und TypeB übernimmt.

Ich schrieb den folgenden Code:

#include <iostream> 

template<class TypeA, class TypeB> 
struct Test 
{ 
    TypeA t1obj; 
    TypeB t2obj; 
    Test(const TypeA& t1, const TypeB& t2) 
     : t1obj(t1), t2obj(t2) {std::cout<<"Test::Type1, Type2\n";} 
}; 


template<class Type1, 
     template<typename TypeX, typename TypeY> class Type2 > 
struct Test2 
{ 
    Type1 t1obj; 
    Type2<typename TypeX, typename TypeY> t2obj; //Line 17 

    Test2(const Type1& t1, 
      const Type2<typename TypeX, typename TypeY>& t2) //Line 20 
     : t1obj(t1), t2obj(t2) { std::cout<<"Test2::Type1, Type2\n";} 

    Test2(const Type1& t1, 
      const TypeX& x, 
      const TypeY& y) 
     : t1obj(t1), t2obj(x,y) { std::cout<<"Test2::Type1, X, Y\n";} 

}; 

int main() 
{ 
    Test<int, char> obj1(1,'a'); 

    Test2<int, Test<int, char> > strangeobj1(10,obj1); 
    Test2<int, Test<int, char> > strangeobj2(1,2,'b'); 

} 

Ich habe viel versucht, aber ich wirklich absurd Fehler wie:

wrong number of template arguments (1, should be 2) auf der Linie 17 und 20.

+1

Stellen Sie sicher, dass Sie die _first_Fehlermeldung posten. Der Rest könnte gefälscht sein. Und bitte geben Sie die Zeile im Code an. – sbi

+0

@sbi: Der Fehler, den ich erwähnte, ist der erste Fehler, den ich bekomme. –

+0

Das war nicht klar aus Ihrer Beschreibung, also dachte ich, ich würde es erwähnen. – sbi

Antwort

6

Es spielt keine‘ So arbeiten Sie so. Test<int, char> ist eine vollständige Typ, anstelle einer Vorlage. So müssen Sie Typparameter

template<class Type1, 
     class Type2 > 
struct Test2 
{ 
    Type1 t1obj; 
    Type2 t2obj; //Line 17 

    Test2(const Type1& t1, 
      const Type2& t2) //Line 20 
     : t1obj(t1), t2obj(t2) { std::cout<<"Test2::Type1, Type2\n";} 

    Test2(const Type1& t1, 
      const typename Type2::a_type& x, 
      const typename Type2::b_type& y) 
     : t1obj(t1), t2obj(x,y) { std::cout<<"Test2::Type1, X, Y\n";} 

}; 

Für immer TypeX und TypeY ist es sinnvoll, sie zu exportieren, um sie in Test2 verwenden können, wie oben gezeigt.

template<class TypeA, class TypeB> 
struct Test 
{ 
    typedef TypeA a_type; 
    typedef TypeB b_type; 

    // and using them, to show their meaning 
    a_type t1obj; 
    b_type t2obj; 

    Test(const a_type& t1, const b_type& t2) 
     : t1obj(t1), t2obj(t2) {std::cout<<"Test::Type1, Type2\n";} 
}; 

Seien Sie sicher, Where to put the "template" and "typename" on dependent names zu verstehen, zu lesen, warum und wann wie oben typename vor Typnamen zu verwenden.

+0

Aber, warum nicht Template Template Argumente hier arbeiten, um die Argumente für Type2 zu bekommen ?? Könnten Sie auch den Grund für den erwähnten Fehler erläutern? –

+0

Ich denke, C++ 0x variadic Templates wären hier ziemlich nützlich, 'Test2' müsste nichts über die Argumente wissen, die' Type2's Konstruktor benötigt. –

+0

@Ben korrekt. Wir könnten eine partielle Spezialisierung von 'Test2' schreiben, die die Template-Argumente automatisch ableitet, ohne auf festgelegte benannte Typedefs angewiesen zu sein. –

0

Type1 ist ein Typ, Type2 ist eine Vorlage. Was genau denkst du, TypeX und TypeY sind definiert? In der Zeile template<typename TypeX, typename TypeY> class Type2 > werden sie ignoriert.

0

Hier ist eine Option:

#include <iostream> 

template<class TypeA, class TypeB> 
struct Test 
{ 
    TypeA t1obj; 
    TypeB t2obj; 
    Test(const TypeA& t1, const TypeB& t2) 
     : t1obj(t1), t2obj(t2) {std::cout<<"Test::Type1, Type2\n";} 
}; 


template<class Type1, typename TypeX, typename TypeY, 
     template <typename TypeXi, typename TypeYi> class Type2> 
struct Test2 
{ 
    Type1 t1obj; 
    Type2<typename TypeX, typename TypeY> t2obj; //Line 17 

    Test2(const Type1& t1, 
      const Type2<typename TypeX, typename TypeY>& t2) //Line 20 
     : t1obj(t1), t2obj(t2) { std::cout<<"Test2::Type1, Type2\n";} 

    Test2(const Type1& t1, 
      const TypeX& x, 
      const TypeY& y) 
     : t1obj(t1), t2obj(x,y) { std::cout<<"Test2::Type1, X, Y\n";} 

}; 

int main() 
{ 
    Test<int, char> obj1(1,'a'); 

    Test2<int, int, char, Test> strangeobj1(10,obj1); 
    Test2<int, int, char, Test> strangeobj2(1,2,'b'); 

} 
+0

Es ist 'Type2 ', nicht 'Type2 '. 'TypeX' und' TypeY' sind keine abhängigen Namen. –

+0

Vielleicht. Dem Compiler scheint das egal zu sein. – Reinderien

+0

@Ben siehe http://stackoverflow.com/questions/4231502/typename-template-and-dependent-names. Sie sind abhängig von unqualifizierten Namen. Deshalb ist es syntaktisch ungültig. Bitte lassen Sie mich Ihre Meinung zu diesem FAQ-Eintrag hören. –

1

Es gibt mehrere Fehler mit diesem, aber der Hauptfehler scheint zu sein, dass

Test2<int, Test<int, char> > 

nicht, wie Sie eine Vorlage Template-Parameter übergeben. Dies wäre mit geben

Test2<int, Test> 

Das liegt daran, dass Test ist eine Vorlage aber Test<int, char> ist ein Typ (generiert aus dieser Vorlage.)

0

Test<int, char> ist kein Spiel für template<typename TypeX, typename TypeY> class Type2

Die erste ist eine Instantiierung einer Template-Klasse, sie akzeptiert keine Parameter.Die zweite ist ein Vorlagenklassenmuster, das zwei Parameter akzeptiert.

Verwandte Themen