Implement Visitor pattern using shared_ptr