explicit initialization of a template function
-
template <class TList> class TypesConvertor { public: ... //Andere Funktionen template <class T> struct isRegistred : mpl::not_< typename boost::is_same< typename mpl::find<TList, T>::type, typename mpl::end<TList>::type >::type > { }; template <class T> typename boost::enable_if<isRegistred<T>, T>::type getFromStack(lua_State*, int idx) { //... } }; template <class TList> template <> int TypesConvertor<TList>::getFromStack<int>(lua_State*, int idx) { ... }So funktioniert es nicht: gcc 4.4 sagt, dass
invalid explicit specialization before '>' token ..enclosing class templates are not explicitly specialized
Das kann man verstehen, denn
"the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well"
Gibt es Ideen, wie man das Programm zum laufen bringen kann?
-
Du könntest die Spezialisierung in der Definition von TypesConvertor definieren, ggf. indem du dort eine nicht-template-Funktion aufrufst. Oder du löst das ganze per Überladung, d.h.
template <class TList> class TypesConvertor { public: ... template <class T> typename boost::enable_if<boost::mpl::and_<isRegistred<T>,boost::mpl::not_<boost::is_same<T,int>>>,T>::type getFromStack(lua_State*, int idx); template <class T> typename boost::enable_if<boost::mpl::and_<isRegistred<T>,boost::is_same<T,int>>,T>::type getFromStack(lua_State*, int idx); };
-
indem du dort eine nicht-template-Funktion aufrufst
Beispiel?
template <class TList> class TypesConvertor { public: ... template <class T> typename boost::enable_if<boost::mpl::and_<isRegistred<T>,boost::mpl::not_<boost::is_same<T,int>>>,T>::type getFromStack(lua_State*, int idx); template <class T> typename boost::enable_if<boost::mpl::and_<isRegistred<T>,boost::is_same<T,int>>,T>::type getFromStack(lua_State*, int idx); };Dies fürchte ich wird nicht klappen, denn außer der Überladung mit "int" gibt es noch zahlreiche andere. Es wird sehr schnell schrecklich aussehen..
-
CppCoder schrieb:
denn außer der Überladung mit "int" gibt es noch zahlreiche andere.
für jeden einzelnen potentiell registrierten Typ?
-
für jeden einzelnen potentiell registrierten Typ?
nein, in TList werden nur Objekttypen(Klassen) registriert. es ist so gedacht, dass sie mit einer generic-funktion "template <class T> ... getFromStack(...)" die in der Klass Scope liegt, verarbeitet werden. Für alle andere Typen( Zahlentypen wie int float... const char*) soll es eigene Überladungen geben.
-
Explizite Memberspezialisierungen ohne explizite Spezialisierung des äußeren Templates sind verboten, eine vergleichbare Regel existiert nicht für partielle Spezialisierungen. Man könnte also so etwas machen:
template <class TList> class TypesConvertor { public: ... //Andere Funktionen template <class T> struct isRegistred : boost::mpl::contains<TList,T>::type {}; template <class T> typename boost::enable_if<isRegistred<T>, T>::type getFromStack(lua_State* state, int idx) { GetFromStack<T,void>()(this, state, idx); } private: template <typename T, typename dummy> struct GetFromStack { T operator()(TypesConvertor* p, lua_State* state, int idx) { ... } }; template <typename T, typename dummy> friend struct GetFromStack; }; template <typename TList> template <typename dummy> struct TypesConvertor<TList>::GetFromStack<int, dummy> { int operator()(TypesConvertor* p, lua_State* state, int idx) { ... } };ist auch nicht besonders schön.