5

I want to implement an algorithm as a class deriving from a pure virtual class representing the kind of problem the particular algorithm solves.

The general interface would look like this:

template<typename A, typename B>
class ISolutionToProblem
{
public:
    virtual void Init(const A & input, const B & param) = 0;
    virtual const B & ComputeSolution() = 0;

    virtual ~ISolutionToProblem() {}
};

And the implementation would be for example:

template<typename T>
class MyAlgorithm:
    public ISolutionToProblem<typename MyAlgorithm<T>::WorkData, T>
{
public:
    struct WorkData { /* Stuff using T... */ };
    virtual void Init(const WorkData & input, const T & param);
    virtual const T & ComputeSolution();

virtual ~MyAlgorithm();
};

(to be more specific, the problem is actually path finding, but I don't think it is relevant)

My problem is the inheritance part: I am using a nested struct as a template parameter, and no matter how nicely I try to talk to the compiler, it keeps refusing to compile my code.

I could go lazy and just put the inner structure outside of the class, but if possible I'd prefer it to stay neatly placed in the class.

  1. So is what I am trying to do actually possible (in C++98)?
  2. If so, how should I write it ? (bonus points if you get me to understand why the syntax doesn't accept the form above)
  3. Otherwise, what am I doing wrong? (is my design flawed to begin with?)

Here is how the compiler error looks like.

  • g++ (4.8):
    error: no type named ‘WorkData’ in ‘class MyAlgorithm<int>’
  • clang (3.1):
    error: no type named 'WorkData' in 'MyAlgorithm<T>'
  • VS2012:
    error C2146: syntax error : missing ',' before identifier 'WorkData'
    see reference to class template instantiation 'MyAlgorithm<T>' being compiled
    error C2065: 'WorkData' : undeclared identifier
    error C2955: 'ISolutionToProblem' :
                 use of class template requires template argument list
    see declaration of 'ISolutionToProblem'
Julien Guertault
  • 1,324
  • 1
  • 15
  • 25
  • What is `Data` supposed to be? –  Nov 28 '13 at 01:05
  • So what is an example usage and an example compile error? For more experienced users I'm sure it is not necessary but I am curious. –  Nov 28 '13 at 01:11
  • @remyabel: I added the errors detail to the question. Regarding the intent, by encapsulating the algorithm in a class, I can split the execution into steps when I cannot afford to compute everything at once. What I am trying to do with inheritance is to decouple the problem from the solution. This way I could implement a different algorithm, and just switch by instancing one or the other. – Julien Guertault Nov 28 '13 at 01:47
  • @remyabel: for example, instead of `T ComputeSolution()`, it would be `bool ComputeStepsTowardSolution(int maximumSteps)` and `T GetSolution()`. – Julien Guertault Nov 28 '13 at 01:51
  • This looks similar to [In C++, is it possible to have a class inherit from one of its member classes?](http://stackoverflow.com/questions/19923100/in-c-is-it-possible-to-have-a-class-inherit-from-one-of-its-member-classes/19923517). – chwarr Nov 28 '13 at 05:05
  • @c45207: the more I think of it, the more it seems to me it is a forward declaration of nested class problem. If so, then I just cannot do that. – Julien Guertault Nov 29 '13 at 01:14

1 Answers1

2

I think your problem is the the compiler doesn't know what the inner class looks like until it has defined the outer class and the outer class is defined with the inner class as a template parameter. I'm not 100% sure this can't be made to work. The CRTP is an example similar to this that is known to work.

Templates can be used to create inheritance hierarchies, but should not be use the in the definition of a hierarchy. If that sounds confusing, it's because it is. Inheritance and template classes don't mix well. Notice that even though CRTP uses inheritance and templates it does not use virtual functions.

deft_code
  • 57,255
  • 29
  • 141
  • 224
  • Yes it looks that even though the compiler doesn't need to know the outer class to use the inner one, it doesn't have a definition at the moment the inheritance is declared. For now I'm declaring the inner class outside, but I suspect there is something fishy in my design (having both virtual and templates sounds like using mutually exclusive approaches). Also thanks for the link, I didn't know the term. – Julien Guertault Dec 02 '13 at 03:15