c++ - 使用模板派生类的虚拟模板函数访问者解决方法

标签 c++ templates virtual

问题是 template <typename T> virtual void foo()是非法的,我正在尝试使用访问者模式来解决这个问题(众所周知,这通常是有效的)。但是 Base 的派生类是模板类,现在我遇到了访问者类中的虚拟模板问题。如何解决这个问题?

struct Base {
//  template <typename T> virtual void foo() = 0;  // illegal
    virtual void foo (class Visitor& visitor) = 0;  // The attempted solution
};

template <typename D>
struct Derived : Base {
    virtual void foo (Visitor&) override;
};

struct Visitor {
    //template <typename D> // same problem again!
    virtual void visit (Derived<D>*) const = 0;
};

template <typename T, typename D>
struct FooVisitor : Visitor {
    virtual void visit (Derived<D>*) const override {/*Do whatever with T*/}
};

template <typename D>
void Derived<D>::foo (Visitor& visitor) {visitor.visit(this);}

对于所有解决方案,我们假设 D 大约有一百个值,并且不断引入新的 D 类。每个人都会以相同的方式使用 D。为简单起见,我们假设每个访问函数都将使用 D 和

func<D>();

在哪里

template <typename D> void Base::func();

是Base中的一些辅助函数。

最佳答案

这是一个可能有效的解决方案。请注意,这里的假设是您只使用正确的类型进行调用:

struct Base {
    virtual void foo(struct Visitor& visitor) = 0;
};

template <typename D>
struct Derived : Base {
    virtual void foo (Visitor&v) override;
};

struct Visitor {
    virtual ~Visitor() {} // Make this class polymorphic.
};

template <typename D>
struct Visitor_tmpl : public Visitor {
    virtual void visit (Derived<D>*) const {/*Do whatever with T*/}
};

template <typename T, typename D>
struct FooVisitor : Visitor_tmpl<D> {
    virtual void visit (Derived<D>*) const override {/*Do whatever with T*/}
};

template <typename D>
void Derived<D>::foo(Visitor&v) {
    // In this function, D has been bound now to a specific type, so we downcast.
    // It will throw an exception if not the right type.
    dynamic_cast<Visitor_tmpl<D> &>(v).visit(this);
}

int main() {
    Derived<int> d;
    FooVisitor<double, int> v;
    d.foo(v);
}

关于c++ - 使用模板派生类的虚拟模板函数访问者解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27097633/

相关文章:

c++ - 通过指向其非模板父类的指针将模板值分配给类模板

C++ VaSTLy 不同的派生类 - 虚拟方法? Actor ?

c++ - 函数的返回值类型是别名***或 bool 值

当不确定类型是什么时,C++ cast void*

c++ - C++ 中是否存在 typename 关键字,以便向后兼容 “C templates?”

c++ - 使用不同对象时模板特化的多重定义

c++ - 如何从元组创建元组?

c++ - Windows中是否有任何内存虚拟文件API?

c++ - 容器模板参数的 value_type

c++ - 如何使用 OpenMP 并行化此循环?