mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 16:32:12 +00:00
68 lines
1.9 KiB
Plaintext
68 lines
1.9 KiB
Plaintext
:example: ../examples
|
|
|
|
[#multiple_dispatch]
|
|
|
|
A method can have more than one virtual parameter. This is often called
|
|
"multi-method" or "multiple dispatch". All the virtual parameters participate
|
|
equally in overrider selection, following the same rules as those governing
|
|
overload resolution - except that the selection happens at runtime, and takes
|
|
into account the arguments dynamic types.
|
|
|
|
Multiple dispatch is occasionally useful. When it is needed, it can be difficult
|
|
to implement correctly and efficiently by hand. For example, given the following
|
|
classes:
|
|
|
|
[source,c++]
|
|
----
|
|
include::{example}/rolex/7/main.cpp[tag=classes]
|
|
----
|
|
|
|
We want to implement a function - `approve` - that determines who can make what
|
|
kind of expenses. The rules are:
|
|
|
|
- By default, an expense is rejected.
|
|
|
|
- Employees can take any public transportation.
|
|
|
|
- Managers can also take a taxi, for a ride cost up to $100.
|
|
|
|
- Founders can take any transportation, including a private jet.
|
|
|
|
This is a case of multiple dispatch: the outcome depends on two parameters. It
|
|
can be implemented as a method with two virtual arguments. The four rules can be
|
|
expressed as four overriders:
|
|
|
|
[source,c++]
|
|
----
|
|
include::{example}/rolex/7/main.cpp[tag=approve]
|
|
----
|
|
|
|
Because `approve` understands inheritance, we don't have to specify an overrider
|
|
for every combination (5 role classes x 6 expense classes = 30 combinations).
|
|
|
|
### Ambiguities
|
|
|
|
Just like with overload resolution, ambiguities can arise. Let's look at another
|
|
example - matrix addition:
|
|
|
|
[source,c++]
|
|
----
|
|
include::{example}/ambiguities/1/main.cpp[tag=content]
|
|
----
|
|
|
|
The programs terminates with the following error message:
|
|
|
|
```
|
|
ambiguous
|
|
Aborted (core dumped)
|
|
```
|
|
|
|
This is because the call to `add(a, b)` is ambiguous: both overriders are equally
|
|
good matches. The solution is to add an overrider for the case where both
|
|
arguments are `SparseMatrix`:
|
|
|
|
[source,c++]
|
|
----
|
|
include::{example}/ambiguities/2/main.cpp[tag=content]
|
|
----
|