views:

60

answers:

2

I have that template class that uses a policy for it's output and another template argument to determine the type for it's data members. Furthermore the constructor takes pointers to base classes which are stored in private pointers. Functions of this objects shall take a this pointer to the template class to give them access to the data. In code this looks like this:

class ShapeGenerator;

template <typename PointData, typename OutputPolicy> class ModelCreator {
private:
    OutputPolicy output;
    ShapeGenerator* shape
    std::vector<PointData> data;
public:
    ModelCreator (ShapeGenerator *s) : shape(s) { }
    void createShape() { shape->generateShape(this); }
};

ShapeGenerator is an interface and shall be implemented. It looks like this:

class ShapeGenerator {
public:
    void generateShape (ModelCreator* m) = 0;
};

If I compile this with g++ 4.3.4 (cygwin) I get an error in the ShapeGenerator::generateShape saying 'ModelCreater' is not a type. I put in a forward declaration of ModelCreator but it changed nothing. I played with some combinations of types and parameters, for example passing only the vector and then I got an error message that said something about incomplete types. I guess this is the problem here.

So, is it possible to pass a templated type with without specific arguements? If so, how?

edit: I'm not bound to the ModelCreator typename. If I have to write it more template-like this isn't problem. But I would like not to specify the types of ModelCreator in the ShapeCreator object. Is that possible?

edit2: Ok, I guess I was a bit to optimistic with this "design". It would have been nice to just throw in some ingrediences and get a soup. But now the salt has to know about the kind of water in the pot. I'll change the templates to plain old composition. Thanks you guys.

+3  A: 

If you want to use the ModelCreator with "free" template parameters, then you have to make ShapeGenerator a template too:

template <typename PointData, typename OutputPolicy> 
class ShapeGenerator {
public:
    void generateShape (ModelCreator<PointData,OutputPolicy>* m) = 0;
};

or

template <template <typename, typename> class ModelCreator> 
class ShapeGenerator {
public:
    void generateShape (ModelCreator* m) = 0;
};

The second version takes another template as a parameter. You would use it like this:

ShapeGenerator<ModelCreator<PointDataType,OutPutPolicyType> > shapeGenerator; 
inflagranti
+1  A: 

You need to make ShapeGenerate a template class as well:

template <typename PointData, typename OutputPolicy>
class ShapeGenerator;

template <typename PointData, typename OutputPolicy>
class ModelCreator {
private:
    OutputPolicy output;
    ShapeGenerator< PointData, OutputPolicy >* shape;    
    std::vector<PointData> data;
public:
    ModelCreator (ShapeGenerator< PointData, OutputPolicy >* s) : shape(s) { }
    void createShape();
};

template <typename PointData, typename OutputPolicy>
class ShapeGenerator {
public:
    void generateShape (ModelCreator< PointData, OutputPolicy> * m) = 0;
};

template <typename PointData, typename OutputPolicy>
void ModelCreator< PointData, OutputPolicy >::createShape() { shape->generateShape(this); }
sje397