: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 program 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]
----
