c++enumsc++03

Accessing an enum value in a nested templated class in C++03


I have the unfortunate task in 2024 of adding some code to a codebase that needs to be used in a C++03 setting - where unfortunately the original class myclass can't be changed.

I've gotten stuck on something simple which is accessing enum values from an enum that is defined in a nested class.

#include <cstdio>

namespace ns
{
   template <typename T>
   class myclass {
   public:
      enum etype {
         e_option1,
         e_option2,
         e_option3,
         e_option4
      };
   };
}

int main() {
   typedef typename ns::myclass<int> mc_t;
   mc_t::etype et = mc_t::etype::e_option2;

   switch(et) {
      case mc_t::etype::e_option1 : printf("option1\n"); break;
      case mc_t::etype::e_option2 : printf("option2\n"); break;
      case mc_t::etype::e_option3 : printf("option3\n"); break;
      case mc_t::etype::e_option4 : printf("option4\n"); break;
   }

   return 0;
}

https://godbolt.org/z/KeK7M54Wb

<source>: In function 'int main()':
<source>:20:27: error: 'ns::mc_t::etype' is not a class or namespace
   20 |    mc_t::etype et = mc_t::etype::e_option2;
      |                           ^~~~~
<source>:23:18: error: 'ns::mc_t::etype' is not a class or namespace
   23 |       case mc_t::etype::e_option1 : printf("option1\n"); break;
      |                  ^~~~~
<source>:24:18: error: 'ns::mc_t::etype' is not a class or namespace
   24 |       case mc_t::etype::e_option2 : printf("option2\n"); break;
      |                  ^~~~~
<source>:25:18: error: 'ns::mc_t::etype' is not a class or namespace
   25 |       case mc_t::etype::e_option3 : printf("option3\n"); break;
      |                  ^~~~~
<source>:26:18: error: 'ns::mc_t::etype' is not a class or namespace
   26 |       case mc_t::etype::e_option4 : printf("option4\n"); break;
      |                  ^~~~~
Compiler returned: 1

Solution

  • You don't need the extra ::etype when accessing the enumerators in your example of unscoped enumeration as they are already visible in the enclosing scope(which is the class scope here).

    So the modified working code looks like:

    int main()
    {
       typedef typename ns::myclass<int> mc_t;
    //-----------------------v------------->no need to use `etype` here.
       mc_t::etype et = mc_t::e_option2;
    
       switch(et) {
    //---------------v--------------------------------------->no need to use etype here
          case mc_t::e_option1 : printf("option1\n"); break;
          case mc_t::e_option2 : printf("option2\n"); break;
          case mc_t::e_option3 : printf("option3\n"); break;
          case mc_t::e_option4 : printf("option4\n"); break;
       }
    
       return 0;
    }
    

    Working demo