我想知道如何实现像boost::mpl::map这样的模板元编程结构,这是支持常量插入和删除元素以及测试成员资格的结构。< / p>
很难在所有变通方法,宏和生成的代码背后的boost头中找到真正的实现。
答案 0 :(得分:3)
基本上,通过巧妙地使用重载。我们假设您想构建一个只有两个&#34;元素的地图&#34;:T --> U
和X --> Y
。如果我们将所有继承层次结构展平,我们最终会得到一个类似于以下类型的类型:
struct specific_mpl_map {
U get(T );
Y get(X );
template <typename AnythingElse>
void_ get(AnythingElse );
pair<T, U> get(int_<0> );
pair<X, Y> get(int_<1> );
using size = int_<2>;
};
这样,对某些键K
的查找只是decltype(map.get(K{}))
,这是编译时常量 - 你不需要遍历所有对来弄清楚它是什么一个get(K)
。而且您还可以通过调用get(int_<i>{})
来按顺序迭代。任何插入/删除只会创建一个包含所有新的预期get()
函数的新地图类型。
这并不是代码的样子,实际上每个get
都是自己的类型,并且整个事物都是为你添加到地图的每个pair
线性地继承的,但这大致是最终目标。
如果您使用-E
进行编译,然后只看一下被淘汰的内容,这会有所帮助。密钥类型称为m_item
,它为每种类型的查找定义静态函数。因此,如果我们想按键进行查找,则有:
template< typename Key, typename T, typename Base >
struct m_item
: Base // Base is the rest of the map less this element
{
// some typedefs
static aux::type_wrapper<T> value_by_key_(m_item const&,
aux::type_wrapper<Key>*);
using Base::value_by_key_;
};
at
使用了哪个:
template< typename Map, typename Key >
struct m_at
{
typedef aux::type_wrapper<Key> key_;
typedef __typeof__( Map::value_by_key_(
aux::ptr_to_ref(static_cast<Map*>(0)),
static_cast<key_*>(0) )
) type;
};
基本空地图也定义:
template< typename Dummy = na > struct map0
{
static aux::type_wrapper<void_> value_by_key_(map0<> const&,
void const volatile*);
};