Неполный тип в качестве параметра функции?

У меня есть этот класс шаблона, который использует политику для своего вывода и другой аргумент шаблона для определения типа его элементов данных. Кроме того, конструктор принимает указатели на базовые классы, которые хранятся в закрытых указателях. Функции этих объектов должны принимать указатель 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 является интерфейсом и должен быть реализован. Это выглядит так:

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

Если я скомпилирую это с помощью g++ 4.3.4 (cygwin), я получаю сообщение об ошибке в ShapeGenerator::generateShape, говорящее 'ModelCreater' is not a type. Я вставил предварительную декларацию ModelCreator, но это ничего не изменило. Я играл с некоторыми комбинациями типов и параметров, например, передавая только вектор, а затем получил сообщение об ошибке, в котором говорилось что-то о неполных типах. Я думаю, это проблема здесь.

Итак, можно ли передать шаблонный тип без конкретных аргументов? Если да, то как?

Изменить: я не привязан к имени типа ModelCreator. Если мне нужно написать его более шаблонно, это не проблема. Но я бы не хотел указывать типы ModelCreator в объекте ShapeCreator. Это возможно?

edit2: Хорошо, думаю, я был слишком оптимистичен в отношении этого "дизайна". Было бы неплохо просто добавить ингредиенты и получить суп. Но теперь соль должна знать, какая вода в горшке. Я изменю шаблоны на простую старую композицию. Спасибо вам, ребята.


person DaClown    schedule 09.07.2010    source источник
comment
Ваш дизайн нуждается в изменении. Типа ModelCreator нет, это класс-шаблон. Он не может быть параметром вашей функции.   -  person GManNickG    schedule 09.07.2010
comment
Я понял, что шаблон генерирует все функции, которые он использует для всех заданных типов. Так что в итоге получается целая куча перегруженных функций. Поэтому я решил, что с другой функцией должно быть то же самое, компилятор знает тип в то время, когда я создаю его объект.   -  person DaClown    schedule 09.07.2010
comment
Я не уверен, что понимаю, что вы имеете в виду, но шаблоны - это то, что называется экземпляром, когда предоставляются все аргументы шаблона. Компилятор не может обойтись без траты времени на создание каждой функции для каждой комбинации типов.   -  person GManNickG    schedule 09.07.2010
comment
Тогда я был просто неправ. Что я пытаюсь сделать, так это зафиксировать какое-то поведение через политику, а остальное через ранее созданные объекты. Но эта моя шаблонная идея кажется скорее бременем, чем благословением.   -  person DaClown    schedule 09.07.2010


Ответы (2)


Если вы хотите использовать ModelCreator с "бесплатными" параметрами шаблона, вам также нужно сделать ShapeGenerator шаблоном:

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;
};

Вторая версия принимает в качестве параметра другой шаблон. Вы бы использовали это так:

ShapeGenerator<ModelCreator<PointDataType,OutPutPolicyType> > shapeGenerator; 
person Janick Bernet    schedule 09.07.2010

Вам также нужно сделать ShapeGenerate классом шаблона:

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); }
person sje397    schedule 09.07.2010