(本节示例的来源请参见 multi.cpp)
操作可以具有一个以上的 any 参数。我们以二元加法为例。
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
这不是一个多态方法(multimethod)。+ 参数的底层类型必须相同,否则行为未定义。此示例是正确的,因为参数都持有 int。
![]() |
注意 |
|---|---|
添加 |
addable<> 要求参数的类型完全相同。但这并不涵盖加法的所有用法。例如,指针算术需要一个指针和一个整数,并返回一个指针。我们可以通过为涉及的每种类型分配一个占位符来捕获这种类型之间的关系。我们将占位符 _a 表示指针,占位符 _b 表示整数。
int array[5]; typedef mpl::vector< copy_constructible<_a>, copy_constructible<_b>, typeid_<_a>, addable<_a, _b, _a> > requirements;
我们的新概念 addable<_a, _b, _a> 捕获了指针加法的规则:_a + _b -> _a。
此外,我们不能再独立地捕获变量了。
any<requirements, _a> ptr(&array[0]); // illegal
这行不通,因为在捕获概念绑定时,库需要知道 _b 绑定到什么类型。我们在构造 any 时需要指定两个占位符的绑定。
typedef mpl::map<mpl::pair<_a, int*>, mpl::pair<_b, int> > types; any<requirements, _a> ptr(&array[0], make_binding<types>()); any<requirements, _b> idx(2, make_binding<types>()); any<requirements, _a> x(ptr + idx); // x now holds array + 2
现在 + 的参数不再是同一类型,我们需要确保两个参数都同意 _a 映射到 int*,并且 _b 映射到 int。
我们还可以使用 tuple 来避免显式写出映射。 tuple 只是一个方便的类,它组合了从其所有参数中获得的占位符绑定。
tuple<requirements, _a, _b> t(&array[0], 2); any<requirements, _a> y(get<0>(t) + get<1>(t));