lundi 17 septembre 2018

How to invoke specific template method in children class

I have a Strategy like pattern, where Strategy interface is IFilter, Context is Context class, Filter1, Filter2... etc are Concrete Strategies, CommonFilter is interlayer between Strategy and Concrete Strategy for some service operations.

Inheritance structure IFilter > CommonFilter > Specific_filters

I have a lot of filter classes, each filter can work with different type of array of numeric data (int, int16, uint16, float, double ... etc). Filters differ from each other, but inside one filter they work equally on different numeric types.

Each filter receives at the input struct - FilterMetaData, which has: a data source, a data type and a data size. At the output, filter produces the same structure. FilterMetaData apply(const FilterMetaData metaData); Filter can take e.g. uint16 data, and outputs uint16, for another filter in chain.

Filters have base class CommonFilter which validates FilterMetaData. CommonFilter implements an interface IFilter;

I have a list of filters QList m_filters; I want to iterate over filter objects like this

class Context {...

for(auto filter : m_filters)
    {
       filterMetaData = filter->apply(filterMetaData);//parse type of previous filter and work with it
    }

And I want that the data type of filter should be selected automatically from the field of the FilterMetaData :: typeOfData structure; So it should be a chain of filters. This chain would be invked multiple times;

So I dont know how to call filter with specific type, i dont want to make type condition in each filter.

p.s. im using old gcc 4.4.7 compiler compatible only with early c++0x

p.p.s added specific filter example. So how can i automaticaly invoke apply< T> in specific filter based on numeric type. If a have Filter1, Filter2 ... FilterN. I dont want to check type in each filter, i want to make it once. All chain of filters must be called, one by one.
e.g.

data in/out    uint16 array       uint16 array      uint8 array  ...
--------->Filter1--------->Filter2--------->Filter3----->...


class IFilter
{
public:
    virtual ~IFilter(){}
    // do filtration
    virtual FilterMetaData apply(const FilterMetaData metaData) = 0;
};


enum TypeOfData
{
    Uint_8,
    Uint_16,
    Float
    ...
};

    class FilterMetaData
{
public:
    void *dataIn;
    TypeOfData typeOfData;
    int numOfElements;
};


class CommonFilter : public QObject, public IFilter
{
    Q_OBJECT
    Q_INTERFACES(IFilter)
public:
    explicit CommonFilter(QObject *parent = nullptr);

public:

    virtual FilterMetaData apply(const FilterMetaData metaData) override = 0;
    const FilterMetaData metaData() const;

protected:
    bool applyMetaData(const FilterMetaData metaData);

private:
    FilterMetaData m_metaData;

};

Example of filter

class Filter1 : public CommonFilter
{
    Q_OBJECT
public:
    explicit Filter1(QObject *parent = nullptr);

    //common type
    FilterMetaData apply(const FilterMetaData metaData) override;

    //filtration for specific type
    template<typename T>
    FilterMetaData apply(const FilterMetaData metaData);
};

Aucun commentaire:

Enregistrer un commentaire