Drop your email below to get engineering updates.

Privacy: no spam, one step unsubscribe. We'll only send high-signal dev content re this and other Boost libraries.


Boost.OpenMethod Library Overview

Introduction

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.

What Are Open Multi-Methods?

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."

Key Benefits

1. Extensibility Without Modification

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.

2. Reduces Coupling

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.

3. Eliminates the Visitor Pattern

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.

4. High 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.

Use Cases

1. Expression Trees and Interpreters

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);
}

2. Polymorphic Operations Across Type Hierarchies

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
}

3. Serialization and I/O Systems

Implementing serialization, logging, or pretty-printing without modifying domain objects or creating complex visitor hierarchies.

4. Plugin and Dynamic Loading Systems

OpenMethod supports dynamic loading on systems with proper C++ template support. Plugins can add new classes, methods, and implementations at runtime.

5. Domain-Specific Language Implementation

Building DSLs where operations on language constructs can be added incrementally without restructuring the entire type system.

6. Game Entity Systems

Managing interactions between different game entity types where behavior depends on the combination of entity types involved (combat systems, collision response, AI behavior).

7. Multi-Format Data Processing

Processing data that can be in multiple formats, where operations need to handle all format combinations (document conversion, protocol translation, data migration).

Technical Highlights

Requirements

Key Features

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.

Design Philosophy

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:

Comparison with Traditional Approaches

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

Getting Started

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!
}

Community and Development

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:

Conclusion

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.