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



下面的例子演示了我的意思:

    #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::type来评估update2时,我插入的项目将消失。

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

我确信这是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> > > >

并且访问其类型一直回到返回CCD_ 19的CCD_。

我记录了一个错误,最初是在发布这个答案之前等待回应,但4周后,我决定在没有他们任何答案的情况下发布这个。

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

最新更新