Является ли шаблон посетителя самым быстрым способом определения типа параметра метода (фактически одной отправки по параметру, а не по классу члена) в C ++?Я мог бы знать точные методы, которые я хочу вызывать для элементов еще не известного подтипа, поэтому создание дополнительного вызова виртуального метода, такого как 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), что AFAIK невозможно с лестницами 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()
, но яне думайте, что для этого существует известный чистый шаблон.Я просто делал прямые статические перегрузки и назвал это днем.В любом случае, мое желание инкапсулировать перегрузку внутри функции, вероятно, в лучшем случае сомнительная цель.Спасибо, Морис за ответ.