Is the Visitor Pattern the fastest way to accomplish method parameter type identification (effectively single dispatch on a parameter, not a member's class) in C++? I might know the exact method(s) I want to invoke on elements of not-yet-know subtype, so invariably making an additional virtual method call like V::visit(A *)
in A::accept(V &v) { v.visit(this); }
is undesirable.
// 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
I'd like something functionally equivalent the following but with O(1) cost, which is AFAIK not possible with dynamic_cast<> or typeid() ladders, since std::type_info
can't be a 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;
}
What are my options here? Thanks for the advice!
Edit: Changed sample code to feed results through field, such that multiple signatures aren't needed for different method types. Thanks, Maurice!
Final decision: In addition to not liking the mandatory double dispatch cost of the Visitor Pattern, I also wanted to avoid the interface bloat of overloading foo()
, but I don't think that there is a known clean pattern to do this. I ended up just doing straight static overloads and called it a day. Anyway, my wanting to encapsulate overloading inside a function is probably a questionable goal at best. Thanks, Maurice for the response.