¿Es el patrón de visitante la forma más rápida de lograr la identificación del tipo de parámetro del método (efectivamente envío único en un parámetro, no una clase de miembro) en C++? Puede que sepa el (los) método (s) exacto (s) que quiero invocar en los elementos del subtipo aún no conocido, por lo que invariablemente hacer una llamada al método virtual adicional como V::visit(A *)
en A::accept(V &v) { v.visit(this); }
es indeseable.¿Es el patrón de visitante la forma más rápida de diferenciar tipos de parámetros en C++?
// 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
me gustaría algo funcionalmente equivalente a los siguientes, pero con O (1) costo, que yo sepa no es posible con dynamic_cast <> o typeid() escaleras, ya que std::type_info
no puede haber un constexpr/conmutable.
// 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;
}
¿Cuáles son mis opciones aquí? ¡Gracias por el consejo!
Editar: Se modificó el código de muestra para los resultados de alimentación a través del campo, por lo que no se necesitan múltiples firmas para diferentes tipos de métodos. Gracias, Maurice!
Decisión final: Además de que no le gustaba el costo de envío de doble obligatoria del patrón del visitante, yo también quería evitar los excesos de interfaz de sobrecargar foo()
, pero no creo que hay un patrón conocido limpia a hacer esto. Terminé haciendo sobrecargas estáticas rectas y lo llamé un día. De todos modos, mi deseo de encapsular la sobrecarga dentro de una función es probablemente un objetivo cuestionable en el mejor de los casos. Gracias, Maurice por la respuesta.
para lectores después de C++ 11: eche un vistazo a la biblioteca Yorel Multimethod (que está en Boost ahora) –