【发布时间】:2014-11-24 03:55:47
【问题描述】:
问题是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 中的一些辅助函数。
【问题讨论】:
-
你想在你的模板中做什么
virtual void foo(); ? -
这是一个普遍的问题,不是吗?解决方案应该独立于 T 的意图。也许对于 T 的某些目标可能有一个特殊的解决方案,但需要有一个始终有效的通用解决方案。
-
如何将模板
foo() 设为非虚拟,然后从 foo() 调用虚拟 fooImpl()? -
你需要在
Derived<D>::foo()做一个downcast。 -
您的
Visitor应该为您所期望的每个D提供virtual void visit (Derived<D>*) const = 0;。