jeudi 3 janvier 2019

How do I get around for not allowing templated virtual function

How do I work around for not having the support for templated virtual function?

I have a requirement to create a Builder/Command class which can store templated argument which is used later to call methods to do some processing.

Basically builder should be able to store templated values, maybe there is a different(more correct) way of doing it.

After setting all the values, later I want to call an execute method which will use the templated values to call an internal method.

class BuilderImpl {
public:
    virtual void execute() = 0;
    virtual int type() = 0;
private:
    // common properties here
};

template <typename T1, typename T2>
class BuilderImpl2: public BuilderImpl {
public:
    BuilderImpl2(const T1 &v1, const T2 &v2) : mVar1{v1}, mVar2{v2} {
    }

    virtual void execute() override {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

    virtual int type() override {
        return 2;
    }


    T1 mVar1;
    T2 mVar2;
};


template <typename T>
class BuilderImpl1: public BuilderImpl {
public:
    typedef BuilderImpl1<T> CLAZZ;

    BuilderImpl1(const T &v) : mVar1{v} {
    }

    virtual void execute() override {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

    virtual int type() override {
        return 1;
    }

    template <typename T2>
    std::shared_ptr<BuilderImpl> add(const T2 &v2) {
        return std::make_shared<BuilderImpl2<T, T2>>(mVar1, v2);
    }

    T mVar1;
};

class Builder {
public:
    void execute() {
        std::cout << __FUNCTION__ << std::endl;

        if (mImpl) {
            mImpl->execute();
        }
    }

    template <typename T>
    void add(const T &v) {
        if (!mImpl) {
            mImpl = std::make_shared<BuilderImpl1<T>>(v);
        } else if (mImpl->type() == 1) {
            // How do I update my implementation mImpl to point with an instance of BuilderImpl2, any trick?
            //mImpl = std::static_pointer_cast<BuilderImpl1<???>>(mImpl)->add(v);
        }
    }

protected:
    std::shared_ptr<BuilderImpl> mImpl{ nullptr };
};

void templatebuilder() {
    Builder builder;
    builder.add(10);
    builder.add(0.0);
    builder.execute();
}

Aucun commentaire:

Enregistrer un commentaire