Kevin
Kevin

Reputation: 530

Using type defined in derived class from base class

I have a pure virtual template base class, in which I define a method get_value which takes an enumeration and returns an int. The complication is that each derived class will use a different enumeration. This isn't a problem if I just define the enumerations beforehand and pass them as template parameters to the base, however, since the enum type is directly related to the derived type, I want the enum to be defined within the derived class.

I was hoping to solve this by having the base class take the derived class as a parameter and then access the derived class's enum, like this:

template <typename child_type>
class base_type{
public:
    int get_value(typename child_type::enum_type);
};

class child : public base_type<child>{
public:
    enum enum_type{a,b,c};
};

MinGW reports

test.cpp: In instantiation of 'class base_type<child>':
test.cpp:7:22:   required from here
test.cpp:4:6: error: invalid use of incomplete type 'class child'
  int get_value(typename child_type::enum_type index);
      ^~~~~~~~~
test.cpp:7:7: note: forward declaration of 'class child'
 class child : public base_type<child>{
       ^~~~~

I understand the errors; I just feel like there should be a way to do what I want to do and can't wrap my head around how to do it without getting too complicated. Is this possible, or am I going about it in the wrong way?

As for the specifics of my problem: the classes parse a record file which can be encoded in one of a few different encoding versions - the processing is mostly the same between versions and the bulk can be done in a non-virtual base function, with a call to a virtual function to do version-specific things. Different versions also extract slightly different value names, which I am trying to capture in the version-specific enums. The position of each named value inside the record will be stored in the value of the corresponding enum member value.

There's probably a better way to go about it but I haven't been able to think of it. I suppose in this case I could just have get_value take an int in the base class, use the child class enums to make the call, and just let the cast happen, but I was hoping to see if the more general case of a base class using a type defined in a child was possible.

Upvotes: 0

Views: 1118

Answers (1)

Werner Erasmus
Werner Erasmus

Reputation: 4076

The best solution I can think of is using child traits.

template <typename child_type>
class base_type{
public:
    int get_value(typename child_type::enum_type);
};

struct child_traits {
enum enum_type{a,b,c};
};
class child : 
public child_traits, 
public base_type<child_traits>{

};

Upvotes: 1

Related Questions