inserted items disappear from boost::mpl::map

我只是一个虾纸丫 提交于 2019-12-11 00:46:52

问题


The following example demonstrates what I mean:

    #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());
    }

outputs:

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

When I evaluate update2 by accessing update2::type the items I inserted disappear.

Why does this happen and what can I do to to make sure the evaluating update2 doesn't remove the inserted elements?


回答1:


I'm convinced this is a bug in boost::mpl.

The result of inserting an element into an mpl::map is not an item of type mpl::map but of mpl::m_item. This m_item holds the newly inserted key and value as well as the map they were inserted into.
Now every class in boost::mpl is a metafunction, containers are a metafunction that return themselves. This is useful for situations like this

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

So mpl::map has a typedef inside it that is simply typedef map type;, m_item, however, lacks this typedef and so since it derives from the map it's inserted into m_item::type is actually map::type.

This means my example after insertion (dropping the int_<> for brevity) looks like:

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

and accessing its type reaches all the way back up to map1<pair<1, 1> >::type which returns map<pair<1, 1> > which is why all the inserted items are disappearing.

I logged a bug and was originally waiting for a response before posting this answer but after 4 weeks I decided to post this without any answer from them.

The solution is to simply add typedef m_item type; to boost::mpl::m_item in boost/mpl/map/aux_/item.hpp. This will make m_item a metafunction that correctly returns itself and not return the original map.



来源:https://stackoverflow.com/questions/17393496/inserted-items-disappear-from-boostmplmap

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!