插入的项目从boost :: mpl :: map中消失

时间:2013-06-30 18:25:34

标签: c++ boost-mpl

以下示例演示了我的意思:

    #include <boost/mpl/map.hpp>
    #include <boost/mpl/for_each.hpp>
    #include <boost/mpl/pair.hpp>
    #include <boost/mpl/at.hpp>
    #include <boost/mpl/insert.hpp>
    #include <iostream>

    using namespace boost::mpl;

    template <int n1, int n2>
    struct entry
    {
        typedef pair<int_<n1>, int_<n2> > type;
    };

    typedef map<entry<1,1>::type> entries;

    typedef insert<
        entries, entry<4,4>::type>::type update;

    typedef insert<
        update,
        entry<5,5>::type>::type update2;

    struct print_values
    {
        template <class I>
        void operator()(I)
        {
            std::cout << first<I>::type::value << ", " 
                      << second<I>::type::value << std::endl;
        }
    };

    int main()
    {
        for_each<update2>(print_values());
        std::cout << "Next:" << std::endl;
        for_each<update2::type>(print_values());
    }

输出:

    1, 1
    4, 4
    5, 5
    Next:
    1, 1

当我通过访问update2来评估update2::type时,我插入的项目会消失。

为什么会发生这种情况,我该怎么做才能确保评估update2不会删除插入的元素?

1 个答案:

答案 0 :(得分:2)

我确信这是boost::mpl中的错误。

将元素插入mpl::map的结果不是mpl::map类型的项目,而是mpl::m_item的项目。此m_item包含新插入的键和值以及插入的地图 现在boost::mpl中的每个类都是一个元函数,容器是一个返回自己的元函数。这对于像这样的情况很有用

    typedef map<pair<int,int> > i_map;
    eval_if<true_,
            i_map,
            at<i_map, float> >::type type;

所以mpl::map里面有一个typedef,它只是typedef map type;m_item,但缺少此typedef,因为它来自map它插入到m_item::type实际上是map::type

这意味着我插入后的示例(为了简洁而放弃int_<>)看起来像:

   m_item<5, 5, m_item<4, 4, map1<pair<1, 1> > > >

并且访问其类型一直到map1<pair<1, 1> >::type,返回map<pair<1, 1> >这就是所有插入的项目都消失的原因。

我记录了一个bug,并且在发布此答案之前原本正在等待回复,但在4周之后我决定发布此答案而没有任何答案。

解决方案是在typedef m_item type;中简单地将boost::mpl::m_item添加到boost/mpl/map/aux_/item.hpp。这将使m_item元函数正确返回自身而不返回原始地图。