template spezialisierung
-
hola
ich haeng da gerade bei einem template problem.
ich habe einen base-klasse:template<data_types DATA_TYPE, int WIDTH = 0> class base_type;
nun spezialisiere ich sie fuer verschiedene datentypen die ich als enum klassifiziere:
enum class data_types { unknown = 0, integer = 1, boolean = 2, string = 3, date = 4, time = 5, real = 6 }; /* enum class data_types */ template<> class base_type<data_types::string> : public base_type_interface { public: virtual auto set(const char *str) noexcept -> int; virtual auto get(void) const noexcept -> const char*; virtual auto underlying_data_type(void) const noexcept -> data_types; private: std::string m_string; }; /* class base_type<data_types::string> */ template<> class base_type<data_types::integer> : public base_type_interface { public: virtual auto set(const char *str) noexcept -> int; virtual auto get(void) const noexcept -> const char*; virtual auto underlying_data_type(void) const noexcept -> data_types; private: std::string m_string; }; /* class base_type<data_types::string> */
der 2te template parameter WIDTH ist fuer die strings und fuer die anderen unbeachtet.
nun moechte ich aber weiter spezialisieren. und zwar folgend:
wenn ich data_types::string als template uebergebe und einen int-wert <= 24 fuer WIDTH, moechte ich keinen std::string verwenden sondern ein char[WIDTH].base_type<data_type::string, 24> string_type1; base_type<data_type::string, 300> string_type2;
in pseudoschreibweise moechte cih also folgendes haben:
template<> class base_type<data_types::string, WIDTH<=24> : public base_type_interface { public: virtual auto set(const char *str) noexcept -> int; virtual auto get(void) const noexcept -> const char*; virtual auto underlying_data_type(void) const noexcept -> data_types; private: char m_string[WIDTH]; }; /* class base_type<data_types::string> */ template<> class base_type<data_types::string, WIDTH > 24> : public base_type_interface { public: virtual auto set(const char *str) noexcept -> int; virtual auto get(void) const noexcept -> const char*; virtual auto underlying_data_type(void) const noexcept -> data_types; private: std::string m_string; }; /* class base_type<data_types::string> */
wie stelle ich das an ?
Meep Meep
-
der 2te template parameter WIDTH ist fuer die strings und fuer die anderen unbeachtet.
Komisches Design.
wie stelle ich das an ?
Es gibt mehrere Optionen. Mein Vorschlag ist SFINAE:
template <data_types DATA_TYPE, int WIDTH = 0, typename = void> class base_type; // [...] template <int WIDTH> class base_type<data_types::string, WIDTH, std::enable_if_t<WIDTH<=24>> : public base_type_interface { public: virtual auto set(const char *str) noexcept -> int; virtual auto get(void) const noexcept -> const char*; virtual auto underlying_data_type(void) const noexcept -> data_types; private: char m_string[WIDTH]; }; /* class base_type<data_types::string> */ template <int WIDTH> class base_type<data_types::string, WIDTH, std::enable_if_t<(WIDTH > 24)>> : public base_type_interface { public: virtual auto set(const char *str) noexcept -> int; virtual auto get(void) const noexcept -> const char*; virtual auto underlying_data_type(void) const noexcept -> data_types; private: std::string m_string; }; /* class base_type<data_types::string> */
(ungetestet)
-
Arcoth schrieb:
template <data_types DATA_TYPE, int WIDTH = 0, typename = void>
typename = void
ist mir bewust noch nicht untergekommen. was genau bewirkt der template-parameter ?Meep Meep
-
Das ist nur Platzhalter für die Vorwärst-Deklarierung. Für alle Spezialisierungen, bei denen
data_types
nichtstring
ist, möchtest du ja i.A. nicht die gleiche SFINAE-Option haben, sondern entweder eine andere oder garkeine (also einfachvoid
als Typ).Edit: Außerdem gibst du damit den Typen vor, der durch das
enable_if
dort eingesetzt werden soll.