boost :: mpl :: map(或set)是如何实现的?

时间:2014-11-12 17:30:18

标签: c++ boost boost-mpl

我想知道如何实现像boost::mpl::map这样的模板元编程结构,这是支持常量插入和删除元素以及测试成员资格的结构。< / p>

很难在所有变通方法,宏和生成的代码背后的boost头中找到真正的实现。

1 个答案:

答案 0 :(得分:3)

基本上,通过巧妙地使用重载。我们假设您想构建一个只有两个&#34;元素的地图&#34;:T --> UX --> 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*);
};