Связанный вопрос: link.шаблон для шаблонов, полученных по производным классам
В одном из ответов на вопрос выше мне было рекомендовано использовать шаблон посетителя для решения некоторых проблем с моей структурой наследования классов. Тем не менее, я не уверен, можно ли использовать его в моем контексте, так как мои производные классы могут быть не-типами шаблонов.
Чтобы продемонстрировать проблему, я использовал модифицированный пример кода из этого источника: http://sourcemaking.com/design_patterns/visitor/cpp/2. Очевидно, что приведенный ниже пример не компилируется, так как невозможно определить метод виртуального шаблона. Однако, я считаю, код демонстрирует то, чего я пытаюсь достичь. Существуют ли альтернативы/обходные пути?
// 1. Add an accept(Visitor) method to the "element" hierarchy
class Element
{
public:
virtual void accept(class Visitor &v) = 0;
};
template <unsigned int N>
class This: public Element
{
public:
/*virtual*/void accept(Visitor &v);
string thiss()
{
return "This";
}
};
class That: public Element
{
public:
/*virtual*/void accept(Visitor &v);
string that()
{
return "That";
}
};
// 2. Create a "visitor" base class w/ a visit() method for every "element" type
class Visitor
{
public:
template<unsigned int N>
virtual void visit(This<N> *e) = 0;
virtual void visit(That *e) = 0;
};
template<unsigned int N>
/*virtual*/void This<N>::accept(Visitor &v)
{
v.visit(this);
}
/*virtual*/void That::accept(Visitor &v)
{
v.visit(this);
}
// 3. Create a "visitor" derived class for each "operation" to do on "elements"
class UpVisitor: public Visitor
{
/*virtual*/void visit(This *e)
{
cout << "do Up on " + e->thiss() << '\n';
}
/*virtual*/void visit(That *e)
{
cout << "do Up on " + e->that() << '\n';
}
};
class DownVisitor: public Visitor
{
/*virtual*/void visit(This *e)
{
cout << "do Down on " + e->thiss() << '\n';
}
/*virtual*/void visit(That *e)
{
cout << "do Down on " + e->that() << '\n';
}
};
int main()
{
Element *list[] =
{
new This<3>(), new That()
};
UpVisitor up; // 4. Client creates
DownVisitor down; // "visitor" objects
for (int i = 0; i < 2; i++) list[i]->accept(up);
for (int i = 0; i < 2; i++) list[i]->accept(down);
}