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?


  • Mod

    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..


  • Mod

    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.


  • Mod

    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.


Anmelden zum Antworten