Privacy: no spam, one step unsubscribe. We'll only send high-signal dev content re this and other Boost libraries.
Boost.OpenMethod is a modern C++ library that implements open multi-methods, enabling virtual function dispatch outside of class definitions. The library solves the Expression Problem by allowing developers to add new operations to existing types and new types to existing operations without modifying existing code. OpenMethod was accepted into Boost in May 2025 and is included in Boost 1.90.0.
Open multi-methods (also called open methods or multi-methods) are free functions that support virtual dispatch based on the runtime types of their arguments. Unlike traditional virtual member functions that are defined inside classes, open methods are defined outside the class hierarchy, providing a cleaner separation of concerns between data structures and the operations performed on them.
As Bjarne Stroustrup noted: "In retrospect, I don't think that the object-oriented notation (e.g., x.f(y)) should ever have been introduced. The traditional mathematical notation f(x,y) is sufficient. As a side benefit, the mathematical notation would naturally have given us multi-methods, thereby saving us from the visitor pattern workaround."
New operations can be added to existing type hierarchies without touching the original code. This solves the Expression Problem and conforms to the Open-Closed Principle.
By defining operations outside of classes, OpenMethod helps organize dependencies more effectively. Classes no longer need to know about every operation that might be performed on them, leading to cleaner, more maintainable architectures.
Traditional visitor pattern implementations require intrusive modifications to class hierarchies and complex double-dispatch mechanisms. OpenMethod replaces this with a natural, free-function syntax while maintaining performance.
OpenMethod uses v-tables similar to native virtual functions and can match their performance. The library employs sophisticated dispatch mechanisms that are optimized for both single and multiple dispatch scenarios.
Building evaluators, pretty-printers, or optimizers for abstract syntax trees without cluttering node classes with operation-specific code.
// Define node types once
struct Node { virtual ~Node() {} };
struct Literal : Node { int value; };
struct Plus : Node {
virtual_ptr<Node> left, right;
};
struct Negate : Node {
virtual_ptr<Node> child;
};
// Add operations externally
BOOST_OPENMETHOD(value, (virtual_ptr<Node>), int);
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<Literal> node), int) {
return node->value;
}
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<Plus> node), int) {
return value(node->left) + value(node->right);
}
Implementing operations that dispatch on multiple objects' runtime types simultaneously, such as collision detection, format conversion, or interaction systems.
BOOST_OPENMETHOD(interact,
(virtual_ptr<Animal>, virtual_ptr<Animal>),
void);
BOOST_OPENMETHOD_OVERRIDE(interact,
(virtual_ptr<Herbivore> h, virtual_ptr<Carnivore> c),
void) {
// Herbivore flees from carnivore
}
BOOST_OPENMETHOD_OVERRIDE(interact,
(virtual_ptr<Carnivore> c, virtual_ptr<Herbivore> h),
void) {
// Carnivore hunts herbivore
}
Implementing serialization, logging, or pretty-printing without modifying domain objects or creating complex visitor hierarchies.
OpenMethod supports dynamic loading on systems with proper C++ template support. Plugins can add new classes, methods, and implementations at runtime.
Building DSLs where operations on language constructs can be added incrementally without restructuring the entire type system.
Managing interactions between different game entity types where behavior depends on the combination of entity types involved (combat systems, collision response, AI behavior).
Processing data that can be in multiple formats, where operations need to handle all format combinations (document conversion, protocol translation, data migration).
Virtual Pointers: The library provides virtual_ptr<T> as a wide pointer type (similar to Rust's and Go's) that carries runtime type information needed for dispatch.
Policy-Based Customization: Extensive customization through policies and facets for:
Next Most Specialized Overrider: Mechanism to call the next most specialized overrider, similar to calling a base class method.
Smart Pointer Support: Works with std::shared_ptr and std::unique_ptr (extensible to other smart pointer types) beyond just raw pointers.
Interoperability: Steven Watanabe contributed integration examples with Boost.Any and Boost.TypeErasure during the review process.
OpenMethod follows the design principles outlined in papers by Bjarne Stroustrup and his collaborators (particularly N2216), with refinements based on community feedback during the Boost review process. The library evolved from YOMM2, incorporating years of real-world usage and performance optimization.
The library emphasizes:
f(x, y) instead of object-oriented notation | Aspect | Traditional Virtual Functions | Visitor Pattern | Boost.OpenMethod |
|---|---|---|---|
| Operation Location | Inside classes | Visitor classes | Free functions |
| Adding New Operations | Modify all classes | Add visitor | Add method override |
| Adding New Types | Easy | Modify all visitors | Easy |
| Multiple Dispatch | Requires workarounds | Requires workarounds | Native support |
| Coupling | High | Medium | Low |
| Performance | Fast | Fast | Fast |
OpenMethod can be installed system-wide or added to your project's include path. The main header provides all core functionality:
#include <boost/openmethod.hpp>
#include <boost/openmethod/initialize.hpp>
#include <iostream>
#include <memory>
// Define types
struct Animal { virtual ~Animal() {} };
struct Dog : Animal {};
// Declare method
using boost::openmethod::virtual_ptr;
BOOST_OPENMETHOD(speak, (virtual_ptr<Animal>), void);
// Provide implementations
BOOST_OPENMETHOD_OVERRIDE(speak, (virtual_ptr<Dog>), void) {
std::cout << "Woof!\n";
}
// Register classes
BOOST_OPENMETHOD_CLASSES(Animal, Dog);
// Initialize and use
int main() {
boost::openmethod::initialize();
std::unique_ptr<Animal> rex(new Dog);
speak(*rex); // Prints: Woof!
}
Boost.OpenMethod was developed by Jean-Louis Leroy and underwent rigorous Boost community review managed by Dmitry Arkhipov. The review process refined the library's design, including the policy system and ambiguity handling. The library represents a mature, production-ready implementation built on years of experience with its predecessor, YOMM2.
For more information:
Boost.OpenMethod brings a powerful, elegant solution to problems that traditionally required complex visitor patterns or intrusive class modifications. By enabling free virtual functions with natural syntax, the library helps developers write more maintainable, extensible code while maintaining the performance characteristics of native C++ virtual functions. Whether building interpreters, game engines, or extensible frameworks, OpenMethod provides the tools to cleanly separate operations from data structures.