...one of the most highly
regarded and expertly designed C++ library projects in the
world. — Herb Sutter and Andrei
(For the source of the examples in this section see multi.cpp)
Operations can have more than one
argument. Let's use binary addition as an example.
typedef any< mpl::vector< copy_constructible<>, typeid_<>, addable<>, ostreamable<> > > any_type; any_type x(10); any_type y(7); any_type z(x + y); std::cout << z << std::endl; // prints 17
This is not a multimethod. The underlying types of the
+ must be the same
or the behavior is undefined. This example is correct because the arguments
<> requires the types of the arguments
to be exactly the same. This doesn't cover all uses of addition though. For
example, pointer arithmetic takes a pointer and an integer and returns a pointer.
We can capture this kind of relationship among several types by identifying
each type involved with a placeholder. We'll let the placeholder
_a represent the pointer and the placeholder
_b represent the integer.
int array; typedef mpl::vector< copy_constructible<_a>, copy_constructible<_b>, typeid_<_a>, addable<_a, _b, _a> > requirements;
Our new concept,
addable<_a, _b, _a>
captures the rules of pointer addition:
+ _b -> _a.
Also, we can no longer capture the variables independently.
any<requirements, _a> ptr(&array); // illegal
This doesn't work because the library needs to know the type that _b binds
to when it captures the concept bindings. We need to specify the bindings of
both placeholders when we construct the
typedef mpl::map<mpl::pair<_a, int*>, mpl::pair<_b, int> > types; any<requirements, _a> ptr(&array, make_binding<types>()); any<requirements, _b> idx(2, make_binding<types>()); any<requirements, _a> x(ptr + idx); // x now holds array + 2
Now that the arguments of
the same type, we require that both arguments agree that
_b maps to
We can also use
to avoid having to write out the map out explicitly.
is just a convenience class that combines the placeholder bindings it gets
from all its arguments.
tuple<requirements, _a, _b> t(&array, 2); any<requirements, _a> y(get<0>(t) + get<1>(t));