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.