Keine template template Prameter auf templates mit Standardargumenten?



  • Warum geht z.B. folgender code nicht:

    template<template<class>class List=std::list>
    

    Der MSVC meckert da:

    error C3201: Die Vorlagenparameterliste für die Klassenvorlage 'std::list' stimmt nicht mit der Vorlagenparameterliste für den Vorlagenparameter 'foo' überein
    

    Aber laut Standard darf jeder Compilerhersteller doch mehr template-Parameter machen, wenn sie Standardargumente haben. Soll das heißen ich kann den Code mit geringfügigen Änderungen compilieren, aber dann ist er nicht mehr portierbar?



  • ness schrieb:

    Soll das heißen ich kann den Code mit geringfügigen Änderungen compilieren, aber dann ist er nicht mehr portierbar?

    Portierbar ist er. Nur nicht portabel. Template-Template-Argument müssen *genau* auf den Parameter passen. Sprich: erwartet dein Template-Template-Parameter ein Template mit zwei Parametern, dann muss das Argument ein Template mit zwei Parametern sein. Es hilft auch nicht, wenn zusätzliche Parameter des Arguments Default-Werte haben.

    Da der Standard nur eine minimale Anzahl von Parametern für die std-Container festlegt, nicht aber die genaue, gibt es keine portable Möglichkeit Standard-Container als Argumente für Template-Template-Parameter zu verwenden.

    Mögliche Lösungen:
    a) keine Template-Template-Parameter verwenden. Stattdessen Wrapper mit inneren Template-Klassen.
    b) Wrapper für die Standardcontainer schreiben.



  • Wie würdest du das bei so einem code machen:

    template<class T,template<class>class U>
    struct foo
    {
        U<T> x;
    };
    
    //Aufrufer:
    foo<char,list> v;
    

    Mir ist nicht ganz klar wie du das meinst. Das einzige was mir einfällt wäre define, So das der Aufrufer schreiben muss:

    define STD_TEMPLATE_LIB_PARAMS (class,class,class)
    foo<char,list> v;
    

    oder so.



  • ness schrieb:

    Wie würdest du das bei so einem code machen:

    template<class T,template<class>class U>
    struct foo
    {
        U<T> x;
    };
    

    Entweder a):

    template <class T, class U>
    struct foo
    {
        typename U::template In<T>::Type x;
    };
    
    struct list_w
    {
        template <class T>
        struct In {
            typedef std::list<T> Type;
        };
    };
    
    // Aufrufer:
    foo<int, list_w> f;
    

    oder b)

    template<class T,template<class>class U>
    struct foo
    {
        U<T> x;
    };
    
    template <class T>
    struct list_w : public std::list<T>
    {
        // Ctoren von list
    };
    
    // Aufrufer
    foo<int, list_w> f;
    

    Ich würde immer die erste Variante nehmen und auf Template-Template-Parameter verzichten.


Anmelden zum Antworten