partielle Spezialisierung von static Variablen
-
Hallo,
ich möchte eine Art Lookuptabelle mit Datentypen als Schlüssel. Das ganze habe ich durch eine Traits-Klasse realisiert:template <class T> struct test_traits { static char const * const NAME; }; template <class T> char const * const test_traits<T>::NAME = "Default"; template <> char const * const test_traits<float>::NAME = "FLOAT"; template <class T> char const * const test_traits<typename std::enable_if<std::is_integral<T>::value, T>::type>::NAME = "INT";Durch Spezialisierung wie in der vorletzen Zeile kann ich den einzelen Typen einen Wert zuweisen. Jedoch möchte ich nicht für alle integer Typen eine Spezialisierung schreiben und habe versucht über enable_if und is_integral eine partielle Spezialisierung für Integer-Typen zu realisieren, bekomme aber folgende Fehlermeldung beim compilieren:
error: template definition of non-template 'const char* const test_traits<typename std::enable_if<std::is_integral<_Tp>::value, T>::type>::NAME'
Ich verstehe nur nicht was mir diese Meldung sagen möchte, vor allem warum es ein 'non-template' ist. Andere Vorschläge, wie ich eine Lookuptabelle <datantyp> -> <string> realisieren kann, sind auch willkommen.
Genutzt wird das ganze in einem Funktionstemplate:
template <class T> void test(T const &x) { std::cout << test_traits<T>::NAME << std::endl; }Ich benutze gcc 4.6.1 mit '-std=c++0x'
-
Ich habe eine funktionierende Lösung gefunden:
template <class T, class Enabled = void> struct test_traits { inline static char const * const getName() { return "Default"; } }; template <class T> struct test_traits<T, typename std::enable_if<std::is_floating_point<T>::value >::type> { inline static char const * const getName() { return "FLOAT"; } }; template <class T> struct test_traits<T, typename std::enable_if<std::is_integral<T>::value >::type> { inline static char const * const getName() { return "INT"; } };Mich würde trotzdem interessieren, was genau an meinem ersten Code falsch ist.
-
NomAnor schrieb:
Mich würde trotzdem interessieren, was genau an meinem ersten Code falsch ist.
Partiell spezialisiert werden können nur Klassentemplates, nicht aber statische Member von Klassentemplates.
Mit
template <class T> char const * const test_traits<typename std::enable_if<std::is_integral<T>::value, T>::type>::NAME = "INT";definierst du aber ein statisches Member einer partiellen Spezialisierung, die selbst nie definiert wurde. Das geht nat. nicht. (Anm. selbst wenn eine solche partielle Spezialisierung existieren würde, wäre sie nutzlos; weil das Templateargument nicht deduziert werden könnte).