VS 2010 Template Spezialisierung



  • template<bool b, typename T> int GetElementSize2()
    {
    	return -1;
    }
    template<> int GetElementSize2<true, int>()
    {
    	return sizeof(int);
    }
    template<typename T> int GetElementSize2<true,T>()
    {
    	return sizeof(T);
    }
    

    Bin nach einer Stunde googlen eigentlich der Meinung, dass es so (oder zumindest ganz aehnlich), funktionieren muesste. Zum Beispiel wie hier beim Dictionary<int, Value> http://msdn.microsoft.com/de-de/library/vstudio/3967w96f.aspx

    Beim dritten wird trotzdem immer der Fehler "error C2768: 'GetElementSize2' : illegal use of explicit template arguments" geworfen. Hat jemand einen Tipp, was ich aendern koennte um die gewuenschte Funktionalitaet zu erreichen?



  • Es gibt keine partielle Spezialisierung von Funktionen.



  • Es gibt aber Workarounds. Im Speziellen

    template<bool b, typename T> int GetElementSize2()
    {
        return b ? sizeof(T) : -1;
    }
    

    etwas allgemeiner (C++11)

    template<bool b, typename T> int GetElementSize2()
    {
        return GetElementSize2<T>(std::integral_constant<b>{});
    }
    template<typename T> int GetElementSize2(std::true_type)
    {
        return sizeof(T);
    }
    template<typename T> int GetElementSize2(std::false_type)
    {
        return -1;
    }
    

    oder ganz die Funktion in eine "Partielle Spezialisierung von einer Klassenvorlage" umwandeln.

    template<bool b, typename T> int GetElementSize2()
    {
        return GetElementSize2_klassenvorlage<b, T>::get();
    }
    template<bool b, typename T>
    struct GetElementSize2_klassenvorlage {
      int get() { return -1; }
    };
    template<> struct GetElementSize2_klassenvorlage<true, int> {
      int get() { return sizeof(int); }
    };
    template<typename T> struct GetElementSize2_klassenvorlage<true,T>() {
      int get() { return sizeof(T); }
    };
    

    (alle drei ungetestet)



  • Edit: muss natürlich integral_constant<bool, b> heissen.



  • Danke fuer die Informationen und die Ideen. Ich denke mit mindestens einem davon werde ich es hinbekommen!



  • wörki schrieb:

    template<bool b, typename T> int GetElementSize2()
    {
        return GetElementSize2_klassenvorlage<b, T>::get();
    }
    template<bool b, typename T>
    struct GetElementSize2_klassenvorlage {
      int get() { return -1; }
    };
    template<> struct GetElementSize2_klassenvorlage<true, int> {
      int get() { return sizeof(int); }
    };
    template<typename T> struct GetElementSize2_klassenvorlage<true,T>() {
      int get() { return sizeof(T); }
    };
    

    Besser:

    template<bool b, typename T>
    struct GetElementSize2_klassenvorlage {
      static constexpr int value = -1;
    };
    

    Warum statische Ausdrücke dynamisch machen?



  • Nathan schrieb:

    Warum statische Ausdrücke dynamisch machen?

    Das static habe ich vergessen (das ::get() verrät das).

    Der Code ist so, wie er ist, weil es hier um den allgemeinen Fall geht. Wenn das Resultat constexpr sein soll, kann man das (IMHO immer) schon mit einem Ansatz ähnlich zu b ? sizeof(T) : -1; erschlagen und braucht keine zusätzlichen Funktionen.


Log in to reply