Я хочу реализовать шаблон посетителя для одного из моих классов, не завися от типов, которые будут реализовывать интерфейс для их посещения.
Мое решение было таким:
class model::VisitableNode {
public:
template<class T>
virtual T accept(NodeVisitor<T>);
}
Но С++ говорит, что не поддерживает шаблонные + виртуальные методы.
Node в моем приложении будет иметь только одну реализацию, но если я не использую возвращаемый тип шаблона, мой класс модели будет зависеть от набора инструментов, который я использую для создания графики для своего приложения.
@RSahu Я не думаю, что эта книга, какой бы превосходной она ни была, решает эту проблему. У него есть шаблонный посещаемый класс, похожий на класс этого ответа, но я не думаю, что это то, что нужно людям.
Почему бы не создать шаблон самого класса?
template<class T>
class model::VisitableNode<T> {
public:
virtual T accept(NodeVisitor<T>);
}
Это не имеет особого смысла. OP, скорее всего, хочет применить разных посетителей, возвращающих разные типы, к одному и тому же узлу.
Если посетителю необходимо вернуть значение, обычно возвращаемое значение сохраняется в самом посетителе. Таким образом:
NodeVisitor<double> dv;
node->accept(dv);
double result = dv.result();
Если вам не нравится шаблон, вы можете обернуть его в невиртуальный элемент:
class model::VisitableNode {
public:
template<class T>
/* non-virtual */ T accept(NodeVisitor<T>& v) {
do_accept(v);
return v.result;
}
virtual void do_accept(NodeVisitorBase& v) = 0;
}
Первоначально задуманный шаблон посетителя является довольно плохим шаблоном для использования. Взгляните на переосмысленную версию в Modern C++ Design. Это, скорее всего, будет работать для вашей ситуации.