Nested class as a template parameter of parent class in C++
Asked Answered
C

1

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'
Connel answered 26/11, 2013 at 10:40 Comment(6)
What is Data supposed to be?Avuncular
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.Avuncular
@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.Connel
@remyabel: for example, instead of T ComputeSolution(), it would be bool ComputeStepsTowardSolution(int maximumSteps) and T GetSolution().Connel
This looks similar to In C++, is it possible to have a class inherit from one of its member classes?.Towery
@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.Connel
P
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.

Pubis answered 30/11, 2013 at 18:17 Comment(1)
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.Connel

© 2022 - 2024 — McMap. All rights reserved.