Template-Instantiierung auf bestimme Datentypen begrenzen ?



  • Hi wie kann ich die Instantiierung von Datentypen auf ein Template auf char und wchar_t beschränken... ?

    Ich habe eine Template Klasse geschrieben, die NUR mit char oder wchar_t verwendet werden darf.

    So etwas will ich daher verbieten:

    CKlasse<int> var;
    

    Habt Ihr Ideen ?

    Thx schonmal 😉



  • Sry, aber hab noch ne kleine Frage:
    Kann ich Template-Klassen vererben ?



  • No/Name schrieb:

    Habt Ihr Ideen ?

    Thx schonmal 😉

    Deklariere die Klasse allgemein (keine Implementierung!!). Dann für char und wchar_t spezialisieren.

    No/Name schrieb:

    Sry, aber hab noch ne kleine Frage:
    Kann ich Template-Klassen vererben ?

    Ja. Geht prinzipiell wie bei normalen Klassen.



  • Hallo,
    wenn du es selbst schreiben willst:

    template <bool> struct ASSERT;
    template <> struct ASSERT<true> {typedef int type;};
    
    template <class T, class U>
    struct SameType {
       enum {value = 0};
    };
    
    template <class T>
    struct SameType<T, T> {
       enum {value = 1};
    };
    
    // Deine Klasse
    template <class T>
    class CKlasse {
        typedef typename ASSERT< SameType<T, char>::value || SameType<T, wchar_t>::value>::type ASSERT_TYPE;
    };
    
    int main() {
        CKlasse<char> c;  // OK;
        CKlasse<int> i;   // ERROR;
    }
    

    Einfacher geht es unter Verwendung der Boost-Libs. Da gibt es bereits fertige statische Asserts und alle nötigen Type-Traits-Templates.



  • Menno, hab grad das Kapitel in Modern C++ Design wiederholt und wollte damit glänzen 😉



  • Wow, wat ein Code 😋



  • Nein, Compile-Time. EDIT: (als Antwort auf die,inzwischen wegeditierte, Frage, ob der ERROR zur RT auftreten würde)



  • EDIT; Sorry mein Broswer Spinnt total.... 😞

    Was ist denn 'typename' ?



  • CodeFinder schrieb:

    Was ist denn 'typename' ?

    Das besagt, dass das folgende Konstrukt ein Typ ist und kein Wert.

    Btw. Kannst auch ruhig angemeldet Fragen stellen 😉



  • GPC schrieb:

    Das besagt, dass das folgende Konstrukt ein Typ ist und kein Wert.

    Hm und was ist der Unterschied zu typedef ?

    GPC schrieb:

    Btw. Kannst auch ruhig angemeldet Fragen stellen 😉

    Jo aber ➡

    CodeFinder schrieb:

    EDIT; Sorry mein Broswer Spinnt total.... 😞

    Das ist echt so nervig.... 😡

    Aber dank Dir 😉



  • CodeFinder schrieb:

    GPC schrieb:

    Das besagt, dass das folgende Konstrukt ein Typ ist und kein Wert.

    Hm und was ist der Unterschied zu typedef ?

    Mit typedef kann man einem Typ einen weiteren Namen geben. typename hingegen sagt dem Compiler: "Hey, das was jetzt kommt sollst du bitte als Typ interpretieren und nicht als Wert".

    Weil hinter

    ASSERT< SameType<T, char>::value || SameType<T, wchar_t>::value>::type
    

    könnte ja auch ein Wert stehen. type stellt jedoch einen Typ dar.

    typename kann im Übrigen auch noch als Ersatz für class bei Templates auftauchen:

    template <class T>
    class Foo;
    
    template <typename T>
    class Bar;
    

    Machen beide das gleiche, aber viele benutzen class, wenn für T nur selbstdefinierte Typen (=Klassen) erwartet werden. Kann T auch mal ein eingebauter Datentyp sein (wie int, char), dann nimmt man typename.



  • Hi, bab nochmal n kleines Problemchen, mein Compiler (MS Visual C++ 6.0) zickt beim compilieren mit folgenden Fehlern rum (gekürzt):

    Error Log schrieb:

    [...]
    error C2989: 'SameType<T,T>' : Vorlagenklasse wurde bereits als Nicht-Vorlagenklasse definiert
    error C2988: Unerkannte Vorlagendeklaration/-definition
    error C2027: Verwendung des undefinierten Typs "ASSERT<0>"
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CKlasse<char>'
    error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'ASSERT_TYPE'
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CKlasse<char>'
    error C2501: 'ASSERT_TYPE' : Fehlende Speicherklasse oder Typbezeichner
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CKlasse<char>'
    error C2027: Verwendung des undefinierten Typs "ASSERT<0>"
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CKlasse<int>'
    error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'ASSERT_TYPE'
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CKlasse<int>'
    error C2501: 'ASSERT_TYPE' : Fehlende Speicherklasse oder Typbezeichner
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CKlasse<int>'
    [...]
    CString.exe - 8 Fehler, 0 Warnung(en)

    Der Code ist nahezu unverändert. Ich glaube es liegt am veralteten Compiler, kann das sein ?



  • Ja. Gerade beim Thema Templates ist der VC 6 ne totale Krücke. Okay, er ist auch sonst total veraltet.
    Zieh dir nen aktuellen MinGW oder das Visual Studio 2005 Express Edition. Dann klappt das auch.



  • GPC schrieb:

    Zieh dir nen aktuellen MinGW oder das Visual Studio 2005 Express Edition. Dann klappt das auch.

    Naja bekomm bald die Visual Studio 2005 Team Suite, damit sollte das auch funktionieren 😃 ... thX.



  • @CodeFinder
    Der VC 6.0 unterstützt keine partielle Spezialisierung von Templates. Falls du wirklch auf diesen Compiler angewiesen bist, hilft ein (nicht-konformer) Workaround. Der sieht in etwa so aus (ACHTUNG: ich habe keinen VC 6.0 mehr. Kann das also nicht testen):

    template <class T>
    struct SameTypeImpl {
      template <class U>
      struct In { enum { value = 0 }; };
      // Diese explizite Spezialisierung ist nicht standard-konform. 
      // Funktioniert aber auf dem VC 6.0
      template <>
      struct In<T> { enum { value = 1 }; };
    };
    template <class T, class U>
    struct SameType {
      enum { value = SameTypeImpl<T>::template In<U>::value };
    };
    

    Der Rest nüsste eigentlich funktionieren.

    Damit solche Sachen funktionieren, musst du auf jeden Fall immer mindestens das SP5 für den VC 6.0 installieren.



  • Hm ich hab den Code mal getestet, es verbleiben 3 Fehler:

    Error Log schrieb:

    [...]
    error C2027: Verwendung des undefinierten Typs "ASSERT<0>"
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CString<int>'
    error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'ASSERT_TYPE'
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CString<int>'
    error C2501: 'ASSERT_TYPE' : Fehlende Speicherklasse oder Typbezeichner
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CString<int>'
    [...]

    Aber Du musst Dir jetzt nicht unbedingt die Mühe machen, wie gesagt, ich bekommen bald die Team Suite 😉 .



  • [quote="CodeFinder"]Hm ich hab den Code mal getestet, es verbleiben 3 Fehler:

    Error Log schrieb:

    [...]
    error C2027: Verwendung des undefinierten Typs "ASSERT<0>"
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CString<int>'
    error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'ASSERT_TYPE'
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CString<int>'
    error C2501: 'ASSERT_TYPE' : Fehlende Speicherklasse oder Typbezeichner
    Siehe Verweis auf Instantiierung der kompilierten Klassenvorlage 'CString<int>'
    [...]

    Äh. Das sind doch genau die Fehler, die beabsichtigt sind. Du wolltest, dass man CString nur mit char und wchar_t instanziieren kann. Wenn du es mit int versuchst, kommt die statische Assertions - in Form eines Compiler-Fehlers.



  • @HumeSikkins:
    Ahso, ok; Stimmmt irgendwie einleuchtend 🤡 ...Danke Euch!


Log in to reply