如何干净地将虚拟调用从非模板化父级调度到模板化子级

时间:2016-07-29 16:34:45

标签: c++ templates

我有一个非常难看的实现我要重构的东西,但我不确定如何。这就是我所拥有的:

一些模板化对象

template< typename T>
class Thing { };

界面

class IService {
     public:
          virtual void func(void* arg) = 0;
};

实施它的模板类

template< typename T>
class Service< T> : public IService {
     virtual void func(void* arg) {
          func((Thing< T>* )arg);
     }
     void func(Thing< T>* arg) {
          // do something with arg
     }
};

原因是我想要一个我可以传递的非模板化的IService。模板化IService将通过大型代码库引起大规模重构。

相反,我实例化了服务&lt; T&GT;对象,遍历IService,并使用模板化的Thing对象调用func,这会对实现Thing对象的类似函数执行丑陋的转换。有没有简洁的方法来实现这一点而不模仿IService?

编辑:更多上下文。这就是我真正想要的:

template<typename T>
class IService {
     public:
          virtual void func(Thing<T>* arg) = 0;
};

但是,我无法模板IService。

3 个答案:

答案 0 :(得分:2)

假设您不希望或不能为Thing提供基类,并且假定给定Service<T>只能处理具有相同Thing的{​​{1}} T 1}},你可以这样做:

class IService {
     public:
        template <typename T>
        void func(Thing<T>* arg) {
            auto self = dynamic_cast<Service<T>*>(this);
            if (self) {
                self->func(arg);
            } else {
                // decide how to handle this error
            }
        }
};

func不会是虚拟的。它只是一个模板策略,源自IService需要有func(Thing<T>*)方法。

答案 1 :(得分:1)

也许Thing的某些界面可以解决这个问题?

class IThing { };

template< typename T>
class Thing: public IThing { };

class IService {
     public:
          virtual void func(IThing* arg) = 0;
};

template< typename T>
class Service: public IService {
    virtual void func(IThing* arg) {
        Thing<T> *thing = dynamic_cast<Thing<T> *>(arg);
        if (thing) {
            // implementation
        }
    }
};

答案 2 :(得分:1)

我假设你想通过使用非模板Thing类来清除<T>的{​​{1}}模板参数,而你不关心{{ 1}}在IService的实现中。我不确定这些假设是否正确,但这是一个可能的解决方案。

我还假设T在你的用例中IService内发送{。}}就足够了。

virtual