Поскольку вы теперь пояснили, что вам нужен шаблон посетителей, ну, извините, но это так и есть. Этот ответ показывает, как работает шаблон посетителя с двойной отправкой.
Я подумал о хорошем способе использования CRTP, но это может или не может сработать для вас, в зависимости от обстоятельств.
(Примечание: я использовал код из связанного ответа, поэтому имена не совпадают, но я надеюсь, что вы поняли.)
// your Z
class Visitor;
// superclass needed for generic handling
struct Superbase{
virtual void Accept(Visitor& v) = 0;
};
// your A
template<class Der>
class Base : public Superbase{
public:
void Accept(Visitor& v){
v.Visit(static_cast<Der&>(*this));
}
};
// your B
class Derived1 : public Base<Derived1> {
};
// new C
class Derived2 : public Base<Derived1> {
};
class Visitor {
public:
virtual void Visit(Superbase& sup){
// generic handling of any Superbase-derived type
}
virtual void Visit(Derived1& d1){
// handle Derived1
}
virtual void Visit(Derived2& d2){
// handle Derived1
}
};
int main(){
Visitor v;
Derived1 d1;
d1.Accept(v);
}
Единственная проблема: теперь вы упускаете возможность иметь общий дескриптор для любого типа A
, поскольку функции не могут быть как виртуальными, так и шаблонами.: |
Очистите это, нашли решение, используя базовый класс Superbase
.:) Это даже позволяет вам иметь контейнер Superbase
с и в полной мере использовать полиморфизм.:)