Search code examples
c++c++11templatesenumsclass-template

Using the enum from class template's scope without specyfing template parameters


Having such a code:

template<size_t lines, size_t line_size> class Lcd
{
public:
   enum class Interface : uint8_t
   {
      _8_BIT = 0x30,
      _4_BIT = 0x20,
   };

   Lcd(Interface interface);
   // some other stuff
}
int main()
{
   Lcd<4, 20> lcd(Lcd<4, 20>::Interface::_4_BIT);
}

Could I change the code so that it would be possible to call the Interface enum without using the <4, 20> specifier as the enum is universal?

I would prefer for the enum to be inside the Lcd scope and I need the lines and line_size to be passed through template parameters. Is it fine to just leave it as it is?


Solution

  • Could I change the code so that it would be possible to call the Interface enum without using the <4, 20> specifier as the enum is universal?

    No, it is not possible. As @super already mentioned in the comments, in order to access something inside the template class, you need to specify the template parameters.

    The best you can do is to put the template class in a namespace and place the Interface enums in the namespace outside the class, by which you can avoid the <4, 20>.

    namespace TClasses
    {
       enum class Interface : uint8_t {
          _8_BIT = 0x30,
          _4_BIT = 0x20,
       };
    
       template<std::size_t lines, std::size_t line_size> class Lcd
       {
         // ...code
       };
    }
    

    Now

    TClasses::Lcd<4, 20> lcd{ TClasses::Interface::_4_BIT };
    

    I would prefer for the enum to be inside the Lcd scope and I need the lines and line_size to be passed through template parameters.

    Then there is no other option to use as you have shown. However, if you insist to have less typing, I would suggest an alias template for the Interface outside the class scope.

    // type alias for the Interface
    template<size_t lines, size_t line_size>
    using LcdEnum = typename Lcd<lines, line_size>::Interface;
    

    this will let you write

    Lcd<4, 20> lcd{ LcdEnum<4, 20>::_4_BIT };
    //              ^^^^^^^^^^^^^^^^^^^^^^
    

    In addition if you provide a class template deduction guide for Lcd, you need to mention the <4, 20> only once (i.e. Lcd lcd{ LcdEnum<4u, 20u>::_4_BIT }). That part I leave it you.