(本节示例的来源请参见 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
这不是一个多方法。 +
参数的底层类型必须相同,否则行为未定义。此示例是正确的,因为参数都包含 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));