This week, the last design pattern covered in Implementing QuantLib: the Visitor pattern. Also, a couple of news items. The first is that this past Monday I have released QuantLib 1.11; you can go and download it—after you’re done with this post, hopefully. Some release notes are available, as well as the list of issues and pull requests for this version.
Second bit of news: Hacktoberfest 2017 is underway, and it’s your occasion to contribute to QuantLib (or any other open-source project on GitHub) and get a t-shirt for your effort. It looks like a good deal to me; then again, as you can see, I’m partial to t-shirts myself.
Follow me on Twitter or LinkedIn if you want to be notified of new posts, or subscribe via RSS: the buttons for that are in the footer. Also, I’m available for training, both online and (when possible) on-site: visit my Training page for more information.
The Visitor pattern
Our implementation, shown in the next listing, follows the Acyclic
Visitor pattern  rather than the one in the Gang of Four book :
we defined a degenerate
AcyclicVisitor class, to be used in the
interfaces, and a class template
Visitor which defines the pure
visit method for its template argument.
The pattern also needs support from any class hierarchy that we want to be visitable; an example is shown in the listing that follows.
Each of the classes in the hierarchy (or at least, those that we want
to be specifically visitable) need to define an
accept method that
takes a reference to
AcyclicVisitor. Each of the methods tries to
cast the passed visitor to the specific
Visitor instantiation for
the corresponding class. A successful cast means that the visitor
visit method taking this specific class, so we invoke it.
A failed cast means that we have to look for an fallback. If the
class is not the root of the hierarchy (like
the listing) we can call the base-class implementation of
which in turn will try the cast. If we’re at the root, like the
Event class, we have no further fallback and we raise an
exception. (Another alternative would be to do nothing, but we
preferred not to fail silently.)
Finally, a visitor is implemented as the
BPSCalculator class shown
in this post. It inherits
AcyclicVisitor, so that it can be passed to the various
accept methods, as well as from an instantiation of the
template for each class for which it will provide a
It will be passed to the
accept method of some instance, which will
eventually call one of the
visit methods or raise an exception.
I already discussed the usefulness of the Visitor pattern in the post I mentioned above, so I refer you to it (the unsurprising summary: it depends). Therefore, I will only spend a couple of words on why we chose Acyclic Visitor.
In short, the Gang-of-Four version of Visitor might be a bit faster,
but it’s a lot more intrusive; in particular, every time you add a new
class to the visitable hierarchy you’re also forced to go and add the
visit method to each existing visitor (where by
“forced” I mean that your code wouldn’t compile if you didn’t). With
Acyclic Visitor, you don’t need to do it; the
accept method in your
new class will fail the cast and fallback to its base class. (In fact,
you’re not even required to define an
accept method; you could just
inherit it. However, this would prevent visitors to target this
specific class.) Mind you, this is convenient but not necessarily a
good thing (like a lot of things in life, I might add): you should
review existing visitors anyway, check whether the fallback
implementation makes sense for your class, and add a specific one if
it doesn’t. But I think that the disadvantage of not having the
compiler warn you is more than balanced by the advantage of not having
to write a
visit method for each cash-flow class when, as in
BPSCalculator, a couple will suffice.
 R.C. Martin, Acyclic Visitor. In Pattern Languages of Program Design 3. Addison-Wesley, 1997.
 E. Gamma, R. Helm, R. Johnson and J. Vlissides, Design Patterns: Element of Reusable Object-Oriented Software. Addison-Wesley, 1995.