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


  • Mod

    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 nicht string ist, möchtest du ja i.A. nicht die gleiche SFINAE-Option haben, sondern entweder eine andere oder garkeine (also einfach void als Typ).

    Edit: Außerdem gibst du damit den Typen vor, der durch das enable_if dort eingesetzt werden soll.


Log in to reply