2013-05-05 3 views
0

Я пытаюсь реализовать простую архитектуру типа «трубы и фильтры» в моем приложении. У меня будет общий базовый класс для всех фильтров, имеющих один входной и один тип выходного типа. Я бы зарегистрировал следующий фильтр для всех фильтров, поэтому они образуют простую цепочку. У меня есть одна небольшая проблема: как я должен отображать выходной тип следующего фильтра в качестве параметра типа (например, в прологе?), Вход следующего объекта должен соответствовать выходу текущего фильтра, но текущий фильтр не должен знать тип вывода следующего фильтра).Могут ли быть произвольные параметры шаблона, используемые в C++?

class IFilter 
{ 
    std::auto_ptr<TIn> params; 
    IFilter *nextFilter; 
public: 
    typedef TIn TInType; 
    typedef TOut TOutType; 

    void SetParams(std::auto_ptr<TIn> param) { ...irrelevant code... } 
    virtual void Execute() = 0; 
    void Register(IFilter<TOutType, ???> *filter) { ...irrelevant code... } 
}; 
+0

Вы хотите длинные цепи? Если это так, то создание фильтра с другим изменяет его тип, поэтому результат должен быть другим значением. Вернее, если у вас есть фиотер 'A-> B' и фильтр' B-> C', то результатом их составления является 'A-> C'. Если регистрация просто перехватывает входные данные filter2s для ввода filter1s, я думаю, новое значение не требуется. Следующий вопрос: нужен ли вам абстрактный интерфейс или достаточно шаблон? Как насчет неявного преобразования - 'double' to' int' - вам все равно, хотите его заблокировать или хотите? – Yakk

ответ

0

Просто создать шаблон функции:

template <class In, class Out> 
class Filter 
{ 
public: 
    template <class T> 
    void Register(Filter<Out, T>*) 
    { 

    } 
}; 

int main() 
{ 
    Filter<int, float> f1; 
    Filter<float, double> f2; 
    f1.Register(&f2); 
    return 0; 
} 
0

бы не шаблонной функции работы?

template<typename TIn, typename TOut> 
struct Filter { 
    template<typename NextTOut> 
    void reg(Filter<TOut, NextTOut> *filter) {}; 
}; 

template<typename TIn, typename TOut> 
struct Filter2 : Filter<TIn,TOut> { 
}; 

template<typename TIn, typename TOut> 
struct Filter3 : Filter<TIn,TOut> { 
}; 

int main() 
{ 
    Filter2<int,bool> f2; 
    Filter3<bool,char> f3; 

    f2.reg(&f3); 

} 
0

В принципе, то, что вы говорите, что

Filter<int, float> f1; 
Filter<float, double> f2; 

может быть составлен f1->f2 но не f2->f1. Это довольно тривиально. Вот как это делается:

template<typename Tin, Tout> 
class IFilter { 
    // ... 
    template<typename U> 
    std::auto_ptr<IFilter<Tin, U> > 
    operator->(std::auto_ptr<IFilter<Tout, U> > second) const 
    { 
    return std::auto_ptr<IFilter<Tin, U> >(
     new CompositeFilter(this, second)); 
    } 
}; 

компилятор будет жаловаться, если ему тип выхода первого файлере (Tout) не тип ввода второго фильтра. В этом случае нет соответствия operator->.