Является ли шаблон посетителя самым быстрым способом выполнить идентификацию типа параметра метода (фактически одиночная отправка параметра, а не класса члена) в С++? Я мог бы знать точные методы, которые я хочу вызвать для элементов еще не известного подтипа, поэтому неизменно делать дополнительный вызов виртуального метода, например V::visit(A *)
в A::accept(V &v) { v.visit(this); }
, нежелательно.
// Is the Visitor pattern recommended here? (E inherits D inherits B.)
class Foo {
public:
virtual void visit(B *) { result = 3; }
virtual void visit(D *) { result = 4; }
virtual void visit(E *) { result = 5; }
private:
int result;
}; // class Foo
// Need to add generic interface to B and its children ...
class B {
public:
virtual void accept(class Foo &f) { f.visit(this); }
}; // class B
Я хотел бы что-то функционально эквивалентное следующему, но с затратами O (1), что, насколько мне известно, невозможно с лестницами dynamic_cast‹> или typeid(), поскольку std::type_info
не может быть constexpr/switchable.
// O(n) search cost might get nasty with bigger hierarchies.
int foo(B *b) {
if (typeid(b) == typeid(B *)) { return 1; }
if (typeid(b) == typeid(D *)) { return 2; }
if (typeid(b) == typeid(E *)) { return 3; }
return -1;
}
Каковы мои варианты здесь? Спасибо за совет!
Изменить: образец кода изменен для подачи результатов через поле, чтобы не требовалось несколько подписей для разных типов методов. Спасибо, Морис!
Окончательное решение. Помимо того, что мне не нравилась обязательная двойная стоимость отправки шаблона посетителя, я также хотел избежать раздувания интерфейса из-за перегрузки foo()
, но я не думаю, что существует известный чистый шаблон. сделать это. Я закончил тем, что просто выполнял прямые статические перегрузки и положил на этом день. В любом случае, мое желание инкапсулировать перегрузку внутри функции, вероятно, в лучшем случае сомнительная цель. Спасибо, Морис за ответ.