0

Current Problem:

I need to access an enum from a class that is forward declared, similar to this situation:

Human.h

#include "Dog.h"
class Human{
public:
  enum Language: uint32_t {
    None = 0,
    English = 1,
    Japanese= 2,
  };
}

Dog.h

class Human;

class Dog{
   void understand(Human::Language speech);
}

Dog.cxx

#include "Dog.h"
#include "Human.h"

void Dog::understand(Human::Language speech) {  
   // Do stuff with Human::Language
   return;
}

Errors:

  • The IDE tells me Dog.cxx's implementation is not compatible with Dog.h's deceleration, citing the enum as <erro-type> in the error hint (only red squiggle)
  • When compiling, any mention of the enum in Dog.h/c.xx throws errors, not being able to find the enum

Extra Info:

  • MSVC 15 2017
  • Full architecture of program requires the enum to be accessible like this
  • Forward Deceleration is mandatory in order to solve a circular dependency within my program that is not seen here
  • (1) Do you mean Human::Language instead of Dog::Language in the Dog class? (2) Duplicate - https://stackoverflow.com/questions/13842006/c-forward-declaring-class-scoped-enumeration? – tangy Jan 28 '20 at 05:50
  • where is the definition of `Dog::Language` ? I can only see a definition of `Human::Language` – nivpeled Jan 28 '20 at 05:50
  • My apologies for the mistake, it has been fixed – AlexanderAlexander Jan 28 '20 at 05:51
  • Why does it need to be forward declared? Couldn't you just include the header? Perhaps we need more context. –  Jan 28 '20 at 05:54
  • 3
    Generally, you can't do anything with a forward declared class except declare a pointer to it. – doug Jan 28 '20 at 05:57
  • The forward deceleration is mandatory since it resolves a circular dependency within my program that cannot be seen here – AlexanderAlexander Jan 28 '20 at 06:01

1 Answers1

1

Basically the answer is no, you can't forward declare the enum in this context. Your choices are:

  1. Move the enum into a lightweight base class.
struct HumanBase
{
  enum Language: uint32_t {
    None = 0,
    English = 1,
    Japanese= 2,
  };
};

//fwd declare
struct Human;
  1. Move the enum out of the class.
enum HumanLanguage : uint32_t {
  None = 0,
  English = 1,
  Japanese= 2,
};
struct Human;

and then if you need to later on, you can do:

struct Human
{
  typedef HumanLanguage Language;
};
  1. Change all the method that use the enum to be a template (which may work in some cases, possibly not in others)
class Dog{
   template<typename LanguageType)
   void understand(LanguageType speech);
};
robthebloke
  • 9,331
  • 9
  • 12